Skip to content

Fix materialize dry-run filesystem writes #84

Fix materialize dry-run filesystem writes

Fix materialize dry-run filesystem writes #84

Workflow file for this run

name: ci
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Unit tests
run: python3 tests/test_pkc.py
- run: python3 tests/test_isolation.py
# Glob, not a list. The hand-maintained list drifted: it was missing
# digest, release_notes, thread, federate, and adr_import, all of which
# shipped in 0.4.0 and were never compiled here.
- name: Compile scripts
run: python3 -m py_compile scripts/pkc_*.py scripts/brain_session.py
- name: Validate sample-knowledge
run: python3 scripts/pkc_validate.py --bundle sample-knowledge
- name: Doctor sample-knowledge
run: python3 scripts/pkc_doctor.py --bundle sample-knowledge
- name: Golden context pack + tiny + mermaid
run: |
python3 scripts/pkc_pack.py features/user-authentication.md \
--bundle sample-knowledge --hops 2 --json > /tmp/pack.json
python3 -c "import json; d=json.load(open('/tmp/pack.json')); assert d['node_count']>=5, d; print('pack nodes', d['node_count'])"
python3 scripts/pkc_pack.py features/user-authentication.md \
--bundle sample-knowledge --tiny --json > /tmp/tiny.json
python3 -c "import json; d=json.load(open('/tmp/tiny.json')); assert d['node_count']<=8 and d['hops']==1, d"
python3 scripts/pkc_pack.py features/user-authentication.md \
--bundle sample-knowledge --mermaid | grep -q flowchart
- name: Action items + transcript scrub + PR fixture
run: |
python3 scripts/pkc_action_items.py meetings/2026-08-03-auth-design.md \
--bundle sample-knowledge | tee /tmp/actions.txt
grep -qi "implement\|document" /tmp/actions.txt
python3 scripts/pkc_transcript.py --file tests/fixtures/transcript_speakers.txt --json \
| python3 -c "import json,sys; d=json.load(sys.stdin); assert d['redactions'] or 'REDACTED' in d['notes']"
python3 scripts/pkc_pr_capture.py --json-file tests/fixtures/pr.json \
--repo /tmp/pkc-pr --implements user-authentication \
--author claude-code/lumenfield-detector
- name: Search + digest + release notes + thread + ADR
run: |
python3 scripts/pkc_search.py JWT --bundle sample-knowledge --json | python3 -c "import json,sys; d=json.load(sys.stdin); assert d['count']>=1; assert d['engine'] in ('index','rg','scan')"
python3 scripts/pkc_index.py status --bundle sample-knowledge --json | python3 -c "import json,sys; d=json.load(sys.stdin); assert d['fts5'] is True"
python3 scripts/pkc_digest.py --bundle sample-knowledge --days 3650 --json | python3 -c "import json,sys; d=json.load(sys.stdin); assert 'open_questions' in d"
python3 scripts/pkc_release_notes.py --bundle sample-knowledge | grep -qi release
python3 scripts/pkc_thread.py --file tests/fixtures/thread_slack.txt --json | python3 -c "import json,sys; d=json.load(sys.stdin); assert d['attendees']"
python3 scripts/pkc_adr_import.py --from tests/fixtures/adr --repo /tmp/pkc-adr --dry-run | grep -q proposed
# The hook has exactly two jobs: inject on a Feature, stay silent
# otherwise. Silence is the half that regressions break invisibly, so it
# is asserted, not assumed.
- name: Auto-context hook injects on a Feature and is otherwise silent
run: |
python3 scripts/pkc_auto_context.py --bundle sample-knowledge \
--prompt "recap features/user-authentication.md" > /tmp/inject.json
python3 -c "import json; c=json.load(open('/tmp/inject.json'))['hookSpecificOutput']; \
assert c['hookEventName']=='UserPromptSubmit', c; \
assert 'User authentication' in c['additionalContext']; \
print(len(c['additionalContext']), 'chars injected')"
test -z "$(python3 scripts/pkc_auto_context.py --bundle sample-knowledge \
--prompt 'run the tests and fix what breaks')"
- name: Materialize fixture idempotency
run: |
python3 scripts/pkc_materialize.py --repo /tmp/pkc-ci --bundle knowledge \
--fold tests/fixtures/fold.json \
--author claude-code/lumenfield-detector
python3 scripts/pkc_materialize.py --repo /tmp/pkc-ci --bundle knowledge \
--fold tests/fixtures/fold.json \
--author claude-code/lumenfield-detector | tee /tmp/mat2.txt
grep -q "0 created" /tmp/mat2.txt
# `0 created` was already true before incremental materialize existed --
# write_concept declines to write byte-identical content either way. The
# claim that needs proving is that nothing was RENDERED, which shows up
# as `unchanged` (short-circuited on fingerprint) rather than `skipped`
# (rendered, compared, discarded).
- name: Re-materialize renders nothing
run: |
python3 scripts/pkc_materialize.py --repo /tmp/pkc-ci --bundle knowledge \
--fold tests/fixtures/fold.json --json \
--author claude-code/lumenfield-detector > /tmp/mat3.json
python3 -c "import json; r=json.load(open('/tmp/mat3.json'))['results']; \
a={x['action'] for x in r}; assert a == {'unchanged'}, a; \
print(len(r), 'concepts, none rendered')"
# Rendering nothing is not the same as writing nothing: log.md gained a
# line on every run regardless, so a no-op materialize still diffed.
#
# git, not a checksum: it is the symptom the ticket describes, it names
# the offending file, and `sha256sum` is GNU-only so ci-local.sh could
# not share the check. Do NOT send materialize's stdout to /dev/null --
# it reports a refused write there, and hiding it cost two CI cycles.
- name: Re-materialize leaves the bundle byte-identical
run: |
git -C /tmp/pkc-ci init -q
git -C /tmp/pkc-ci add -A
git -C /tmp/pkc-ci -c user.email=ci@example.com -c user.name=ci commit -qm baseline
python3 scripts/pkc_materialize.py --repo /tmp/pkc-ci --bundle knowledge \
--fold tests/fixtures/fold.json \
--author claude-code/lumenfield-detector
git -C /tmp/pkc-ci status --porcelain > /tmp/dirty.txt
if [ -s /tmp/dirty.txt ]; then
echo "no-op materialize dirtied the bundle:"; cat /tmp/dirty.txt; exit 1
fi
okf-interop:
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Checkout okf-plugin (optional interop)
uses: actions/checkout@v4
with:
repository: SpillwaveSolutions/okf-plugin
path: okf-plugin
- name: okf-graph validate/pack sample when available
run: |
if [[ -f okf-plugin/scripts/okf-graph.py ]]; then
python3 okf-plugin/scripts/okf-graph.py validate sample-knowledge || true
python3 okf-plugin/scripts/okf-graph.py pack sample-knowledge features/user-authentication.md --hops 2 || true
python3 okf-plugin/scripts/okf-graph.py impact sample-knowledge decisions/use-jwt-for-session.md || true
else
echo "okf-plugin not available"
fi