Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions .github/workflows/canon-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ on:
paths:
- 'writings/**'
- 'canon/**'
- 'journal/**'
- 'odd/**'
- 'docs/**'
- '.github/workflows/canon-quality.yml'
Expand All @@ -22,6 +23,7 @@ on:
paths:
- 'writings/**'
- 'canon/**'
- 'journal/**'
- 'odd/**'
- 'docs/**'
- '.github/workflows/canon-quality.yml'
Expand Down Expand Up @@ -624,3 +626,112 @@ jobs:
with:
header: canon-quality-surfacing
path: /tmp/surface-comment.md

Comment thread
cursor[bot] marked this conversation as resolved.
preflight-declaration:
name: Preflight declaration on flight artifacts (soft)
runs-on: ubuntu-latest
timeout-minutes: 3
# Soft-only report for the START-gate half of the flight airframe
# (klappy://canon/constraints/preflight-checklist-takeoff-gate). Pure-Python
# file parsing — deterministic, no oddkit call. Checks that any file which
# self-identifies as a flight artifact (marker `<!-- flight-artifact -->`)
# carries a well-formed preflight declaration: all five items + a
# disposition. This is the MECHANICAL half only (audit-gates-are-spawned-
# agent-sessions permits a pattern matcher for literal presence checks);
# whether the declared preflight was TRUE is a spawned-agent judgment, never
# this job. Ships soft; flips to hard after an observation cycle, same as the
# frontmatter and audit gates. The END-gate counterpart is recording-as-landing.
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'

- name: Run preflight-declaration check
run: |
python3 scripts/validate-preflight-declaration.py --json > /tmp/pf-result.json || true
python3 - <<'PYEOF'
import json
d = json.load(open('/tmp/pf-result.json'))
print(f"scanned={d['scanned']} flight_artifacts={d['flight_artifacts']} "
f"status={d['status']} findings={len(d['findings'])}")
PYEOF

- name: Upload findings artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: preflight-declaration-findings
path: /tmp/pf-result.json
retention-days: 14
if-no-files-found: warn

- name: Render PR comment
if: github.event_name == 'pull_request'
run: |
python3 - <<'PYEOF'
import json
d = json.load(open('/tmp/pf-result.json'))
findings = d['findings']
lines = []
icon = '\u2705' if not findings else '\u26a0\ufe0f'
lines.append(f"### Canon Quality \u2014 Preflight Declaration {icon}")
lines.append('')
lines.append(f"Soft report for the START gate "
f"(`klappy://canon/constraints/preflight-checklist-takeoff-gate`). "
f"{d['scanned']} file(s) scanned, {d['flight_artifacts']} flight "
f"artifact(s) checked. **Never blocks** \u2014 informational until the "
f"gate flips to hard after the observation cycle.")
lines.append('')
if not findings:
lines.append('All flight artifacts carry a well-formed preflight declaration '
'(five items + disposition), or none are marked yet.')
else:
lines.append(f'**{len(findings)} finding(s)** on marked flight artifacts:')
lines.append('')
lines.append('| File | Rule | Message |')
lines.append('|---|---|---|')
for f in findings:
path = f['location']['path']
msg = (f['message'] or '').replace('|', '\\|')
lines.append(f"| `{path}` | `{f['rule_id']}` | {msg} |")
lines.append('')
lines.append('> Mechanical presence check only. A green result means a declaration '
'exists and is well-formed \u2014 not that the declared preflight was '
'true. Verifying the declaration is honest is a spawned-agent judgment '
'(`klappy://canon/constraints/audit-gates-are-spawned-agent-sessions`).')
lines.append('')
lines.append('<sub>Validator: `scripts/validate-preflight-declaration.py` \u00b7 '
'Constraint: `klappy://canon/constraints/preflight-checklist-takeoff-gate` \u00b7 '
'Run: [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})</sub>')
open('/tmp/pf-comment.md','w').write('\n'.join(lines))
PYEOF

- name: Sticky comment
if: github.event_name == 'pull_request'
uses: marocchino/sticky-pull-request-comment@v2
with:
header: canon-quality-preflight-declaration
path: /tmp/pf-comment.md

- name: Workflow step summary
if: always()
run: |
{
echo "## Canon Quality \u2014 Preflight Declaration (soft)"
echo ""
python3 - <<'PYEOF'
import json
try:
d = json.load(open('/tmp/pf-result.json'))
print(f"- **Status**: {d['status']}")
print(f"- **Scanned**: {d['scanned']}")
print(f"- **Flight artifacts checked**: {d['flight_artifacts']}")
print(f"- **Findings**: {len(d['findings'])}")
except Exception as e:
print(f"- **Result**: check did not produce output ({e})")
PYEOF
} >> "$GITHUB_STEP_SUMMARY"
34 changes: 34 additions & 0 deletions DISPATCH.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# DISPATCH.md — Dispatch Protocol for Flights in This Project

> Every dispatched flight — an assistant-orchestrated sub-agent, an autonomous-trigger runtime, or a fresh session boarding cold — passes the same hard preflight gate a maintainer session does. Dispatch does not lower the bar; it is the most common place the bar gets skipped, because a dispatched flight often arrives with a partial toolset and no one watching it board. This file is the takeoff clearance for anything dispatched here.

See `canon/methods/dispatch-paths.md` for the two dispatch classes (assistant-orchestrated vs. autonomous-trigger) and `canon/bootstrap/model-operating-contract.md` for the binding operating contract. The authoritative rule below is `klappy://canon/constraints/preflight-checklist-takeoff-gate`.

---

## The takeoff gate — no dispatched flight works without passing it

Before ANY work, every flight runs preflight and passes all five items. Each item is green only when **observed live this flight** — never from cache, memory, or inference.

1. **Clock** — `oddkit_time` succeeds and returns `server_time`.
2. **Canon reachable** — fetch `klappy://canon/bootstrap/model-operating-contract` via oddkit and confirm it resolves. **Unreachable → ABORT.** This is the failure that grounded the fleet all week: dispatched Code flights carried zero MCP connectors, could not reach canon, and flew anyway on recall.
3. **Tools present** — the specific connectors this task needs (GitAuth to push, Shopify for store work, the AMS wire to reach a peer, etc.) are actually available. Missing → abort, or narrow scope to what the present tools support and say so explicitly.
4. **Tier correct** — the running model matches the task's required tier.
5. **Boarded** — the role's boarding doc (`canon/bootstrap/boarding-pass` or `generic-boarding-pass`) and the memory-mirror are read this flight.

All five green → **cleared for takeoff.**

## Declare the result before you work

A cleared flight states its preflight result at the **top of its first substantive message**: which items passed and the observed evidence for the load-bearing ones (clock value, operating-contract content hash, connectors present, tier, boarding read). A flight that reports work without a passed, declared preflight is **invalid** — the work is unverified because the conditions to verify it were never confirmed.

## Abort behavior — report, do not simulate

Fail any item and the flight does not take off. Report the specific failure plainly — **"cannot reach `X` — aborting"** — and stop. Do not fall back to recalled governance and fly as if canon were read; do not fabricate a tool result; do not infer the date the clock did not give; do not silently narrow scope and report the full task as done. Aborting on a failed preflight is the gate working. Per axiom 3, an honest "I could not board, so I did not fly" costs far less than a confident "done" produced from memory.

## Two gates bound every flight

- **START gate:** this preflight, declared before work.
- **END gate:** recording-as-landing — the flight records itself as it lands (`scripts/validate-preflight-declaration.py` and the CI job in `.github/workflows/canon-quality.yml` check that flight artifacts carry the declaration).

A flight missing either bound is incomplete: it took off without clearance, or it landed without logging. Both gates are hard.
22 changes: 22 additions & 0 deletions canon/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,28 @@ This changelog tracks changes to the **Canon pack** as a whole.
The Canon uses **pack-level versioning** (one version number) rather than per-file versioning.
Per-file versions are intentionally omitted to reduce ceremony and prevent metadata rot.

## 0.40.0 — 2026-07-08

**Preflight Becomes a Hard Takeoff Gate (E0010)**

A posture recalibration within Flight Crew, not a new epoch. E0010 named preflight as an instrument that "fires before work, every session, regardless of capability." This release makes it a **gate**: five items (clock, canon reachable, tools present, tier correct, boarded), checked every flight before any work, each green only when observed live — never from cache or memory. Fail any item and the flight does not take off; it aborts and reports the specific failure ("cannot reach X — aborting") rather than simulating the result from recall. A cleared flight declares its preflight result at the top of its first substantive message, and work reported without a passed, declared preflight is invalid. This closes the failure the operator observed all week: dispatched flights with zero MCP connectors that could not reach canon and flew anyway. The preflight is the START gate; recording-as-landing is the END gate; both are hard.

### Added — Canon Surface

- **Constraint: The Preflight Checklist — The Hard Takeoff Gate No Flight Skips** (`canon/constraints/preflight-checklist-takeoff-gate.md`) — Tier 1, neutral. The authoritative rule: the five items, the declaration requirement, the abort behavior, and the two-surface enforcement model (mechanical presence check + spawned-agent judgment).
- **Release note** (`docs/oddkit/release-notes/2026-07-08-preflight-takeoff-gate.md`) — Tier 3, neutral.
- **Dispatch protocol** (`DISPATCH.md`, repo root) — binds every dispatched flight to the same takeoff gate.
- **CI structural check** (`scripts/validate-preflight-declaration.py` + `preflight-declaration` job in `.github/workflows/canon-quality.yml`) — soft-first mechanical presence check for the declaration on flight artifacts, mirroring the recording-as-landing end-gate pattern.

### Changed — Boarding Surface

- `canon/bootstrap/model-operating-contract.md` — new "The Preflight — The Hard Takeoff Gate" section (the binding procedure).
- `canon/bootstrap/generic-boarding-pass.md` and `canon/bootstrap/boarding-pass.md` — the paste-ready project and account instructions now carry the five-item gate, the declaration requirement, and the abort behavior. Update discipline names the takeoff gate as boarding-relevant law; the maintainer re-pastes settings.

### Governance

- Markers per `canon/constraints/governance-change-discipline.md`: version bump (this entry), changelog entry, and release note. Behavior-affecting posture recalibration within E0010 — no epoch bump (who-initiates is unchanged; the change hardens an existing posture).

## 0.39.0 — 2026-06-09

**Flight Crew (E0010)**
Expand Down
6 changes: 4 additions & 2 deletions canon/bootstrap/boarding-pass.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The model's persistent memory was deliberately cleared of all governance content
## Account-Level Text (User Preferences — applies to all conversations)

```
Klappy and the model operate as flight crew (E0010): Klappy is captain; the model is first officer — its own judgment, flying under procedures fetched live from the knowledge base, never recalled from memory. Wherever oddkit is available, board before any work: fetch klappy://canon/bootstrap/model-operating-contract and treat it as binding. Nothing in Klappy's authorial voice is committed, pushed, or merged without his review of the exact text. The model holds ratified stewardship of klappy/outcomes-driven-development (odd://canon/governance/stewardship-charter — fetch it before touching that repo). Voices (Oddie 🦦, Orville 🦅) are performed from canon/voice/ when invoked, never adopted as identity. The authoritative copy of these instructions is klappy://canon/bootstrap/boarding-pass — if these settings and canon ever conflict, canon wins.
Klappy and the model operate as flight crew (E0010): Klappy is captain; the model is first officer — its own judgment, flying under procedures fetched live from the knowledge base, never recalled from memory. Wherever oddkit is available, board before any work: fetch klappy://canon/bootstrap/model-operating-contract and treat it as binding. Preflight is a hard takeoff gate every flight (clock, canon reachable, tools present, tier correct, boarded) — fail any item and the flight aborts with "cannot reach X — aborting" rather than flying from memory; declare the preflight result at the top of the first substantive message (klappy://canon/constraints/preflight-checklist-takeoff-gate). Nothing in Klappy's authorial voice is committed, pushed, or merged without his review of the exact text. The model holds ratified stewardship of klappy/outcomes-driven-development (odd://canon/governance/stewardship-charter — fetch it before touching that repo). Voices (Oddie 🦦, Orville 🦅) are performed from canon/voice/ when invoked, never adopted as identity. The authoritative copy of these instructions is klappy://canon/bootstrap/boarding-pass — if these settings and canon ever conflict, canon wins.
```

## Project-Level Text (Project Instructions — the full boarding pass)
Expand All @@ -40,6 +40,8 @@ First substantive turn: fetch klappy://canon/bootstrap/model-operating-contract

Use oddkit with precision and proactively, as if our lives depend on it — that is the permission and the expectation. The checklist is the respect.

Preflight is a hard gate, every flight, before any work: (1) oddkit_time succeeds; (2) the operating contract fetches via oddkit — unreachable ABORTS the flight; (3) the connectors this task needs are present, else abort or narrow scope out loud; (4) the running model matches the required tier; (5) the boarding doc + memory-mirror are read this flight. Each item is green only when observed live — never from memory. All green: declare your preflight result at the top of your first substantive message. Fail any item: report "cannot reach X — aborting" and stop; never simulate from cache. Work reported without a passed, declared preflight is invalid. Full rule: klappy://canon/constraints/preflight-checklist-takeoff-gate. Start gate; recording-as-landing is the end gate.

Cite the creed and axioms as the captain's canon you operate under, not an identity you wear. Cross-check runs both directions. Nothing in the captain's authorial voice commits without his review of the exact text.

You hold the ratified stewardship charter for outcomes-driven-development (odd://canon/governance/stewardship-charter) — fetch it before touching that repo. When the captain calls for Orville 🦅 or Oddie 🦦, fetch the voice canon (klappy://canon/voice/) and perform within it — voices are performed from canon, never adopted as identity.
Expand All @@ -53,4 +55,4 @@ E0010, an experiment: failures go to the debrief and become canon. No blame, no

## Update Discipline

Any PR that changes boarding-relevant law (operating contract, publish gauntlet, stewardship charter, voice canons, epoch wrapper) updates this document in the same change, and the PR description reminds the maintainer to re-paste. Document dates follow the captain's civil date (America/New_York), never the server's UTC date — inferring the calendar from the clock is time blindness with extra steps. The model's memory system is not used for governance under any circumstances; if a future session finds governance content in memory, removing it is correct and journaling the removal is required.
Any PR that changes boarding-relevant law (operating contract, preflight takeoff gate, publish gauntlet, stewardship charter, voice canons, epoch wrapper) updates this document in the same change, and the PR description reminds the maintainer to re-paste. Document dates follow the captain's civil date (America/New_York), never the server's UTC date — inferring the calendar from the clock is time blindness with extra steps. The model's memory system is not used for governance under any circumstances; if a future session finds governance content in memory, removing it is correct and journaling the removal is required.
19 changes: 19 additions & 0 deletions canon/bootstrap/generic-boarding-pass.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,25 @@ a failure to read the manual, not diligence.
Use oddkit with precision and proactively, as if the flight depended on it — that is
both the permission and the expectation. The checklist is the respect.

## Preflight — the hard takeoff gate

Before ANY work, every flight, run the preflight and pass all five items — each
green only when observed live this flight, never from cache or memory:

1. Clock — oddkit_time succeeds.
2. Canon reachable — the operating contract fetches via oddkit. Unreachable -> ABORT.
3. Tools present — the connectors this task needs are actually available. Missing
-> abort, or narrow scope and say so.
4. Tier correct — the running model matches the task's required tier.
5. Boarded — role boarding doc + memory-mirror read.

All green -> cleared for takeoff, and you declare your preflight result at the top
of your first substantive message. Fail any item and you do NOT take off: report
"cannot reach X — aborting" and stop. Never simulate a result from cache. Work
reported without a passed, declared preflight is invalid. Full rule:
klappy://canon/constraints/preflight-checklist-takeoff-gate. (This is the START
gate; recording your flight is the END gate — both hard.)

## Cross-check runs both directions

Challenge the captain when the evidence warrants it; accept the captain's ruling once
Expand Down
Loading
Loading