diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml new file mode 100644 index 0000000..dce3d96 --- /dev/null +++ b/.github/workflows/verify.yml @@ -0,0 +1,43 @@ +name: Verify Gates + +on: + push: + branches: [main, 'release-*', 'feat/*'] + pull_request: + branches: [main] + +# No secrets required; safe for forks. +jobs: + verify: + name: Release Gate Verification + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.11', '3.12'] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Run release gate verifier + run: | + chmod +x build/verify-all.py + python3 build/verify-all.py + + - name: Verify surface-scan passes + run: | + python3 build/surface-scan.py + + - name: Verify the composition lock + run: python3 build/check-lock.py kit.lock.json + + - name: Verify ingredient contracts + run: python3 build/check-ingredient-contract.py --lock kit.lock.json + + - name: Run the composition lock tests + run: python3 -m unittest tests.test_kit_lock diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d214451 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,510 @@ +# CHANGELOG + +Dated, per-upgrade log for the Team6-kit public repo. Each entry states what +changed, **why** it changed, and the **evidence/source class** behind it. + +Evidence classes used throughout: + +- **[VERIFIED — internal operating record]** — grounded in a durable internal + operating record of the running Team6 fleet (the team's shared doctrine and + dated session history). These are the team's own derived rules. +- **[VERIFIED — public conceptual source]** — grounded in a public source we + link to below; adopted as a *principle*, never by copying code, prompts, + anti-slop lists, or text. +- **[PROPOSED / PENDING]** — named intent, no durable spec yet. Flagged so a + reader never mistakes it for completed doctrine. + +Licensing note that applies to the whole upgrade: the Erlang/OTP documentation, +`karpathy/autoresearch`, and `NousResearch/autonovel` are referenced as +**conceptual sources only**. Their principles are summarized with attribution; +no source code, prompts, anti-slop lists, or prose is copied into this repo. +`autoresearch`'s README declares MIT but ships no committed `LICENSE` file, and +`autonovel` ships no committed `LICENSE` — both are therefore treated as +weaker-than-committed grants and used for concept only. See `LICENSING.md`. + +v1.2.0 licensing note: **Desert Ant is referenced as an optional implementation +only, never bundled.** This repo does not copy Desert Ant code, model files, or +license text. Desert Ant models carry a separate source-available vendor +license that is distinct from the Apache-2.0 kit layer and does not extend to +it. See `choreography/local-preprocessing.md` and `LICENSING.md`. + +v1.2.0 hosting note (canonical-site decision): the **official public Team6 site** +is https://team6.askaconsult.com. The repository is the source of truth at +https://github.com/ahrazzle/team6-kit. GitHub Pages is not used and the old +Pages site was taken down. The canonical site carries visible navigation back to +https://askaconsult.com/digital/. The deployment and DNS boundary is managed +outside this repository. + +--- + +## Unreleased + +- **What:** add the composition lock and the installer. `kit.lock.json` pins six + standalone ingredients by annotated tag, peeled commit SHA, and tree hash + (`protean-tree-v1`). `install.sh` (a thin entrypoint over `build/install.py`) + resolves a selection, computes the hard `requires` closure, fetches and + verifies each pin, stages and installs in dependency order, and reads every + written file back. Two gates join the release run: `build/check-lock.py` and + `build/check-ingredient-contract.py`. Exit codes are fixed at `0` to `6`, and a + partial install is never reported as success. The composer contains no + ingredient payload and no submodule. + **Why:** the kit needs one command that installs the whole set, an install that + can be verified rather than trusted, and a manifest that a reader can audit + without executing anything. + **Evidence class:** [VERIFIED — internal operating record]; the loader, + the target, and the exit codes were exercised by `tests/test_kit_lock.py` + against fixture repositories. + **License:** the composer zone model is unchanged; each pinned ingredient is + MIT under its own committed `LICENSE` file. See `LICENSING.md`. + +- **What:** add the anti-loop discipline contract. It defines four rules to prevent + thinking loops: load once then use, read once then act, plan once then execute, + and trust tool output as the receipt. Published artifacts and live pages still + require read-back because the deployed state can differ from local state. +- **Why it changed:** agents can enter thinking loops that add zero new information + but consume model budget and time. The previous system had no guard against + redundant operations. +- **Evidence:** [VERIFIED — internal operating record] grounded in the team's shared + doctrine and dated session history. + +- **What:** add the self-improving flywheel contract (`choreography/self-improving-flywheel.md`). +- **Why it changed:** without it, each incident is treated as a one-off and the team + relearns the same lesson; root causes stay in session history and do not + become encoded rules that prevent recurrence. +- **Evidence:** [VERIFIED — internal operating record] + +- **What:** add the open-source contribution contract (`choreography/open-source-contribution.md`). +- **Why it changed:** without it, patches are written on design preference or + assumptions rather than proven defects, risking rejection, wasting time, and + potentially exposing internal context. +- **Evidence:** [VERIFIED — internal operating record] + +- **What:** correct the canonical-site labels in the README. The canonical + public documentation site for Team6-kit is `team6.askaconsult.com`; the + ASKA corporate page at `www.askaconsult.com/team6` is the service listing. + The README previously called the corporate page the "official site" and + the canonical site the "technical guide". +- **Why it changed:** the README labels contradicted the v1.2.0 canonical-site + decision recorded below, which names `team6.askaconsult.com` as the official + public Team6 site. No code, layout, or route behavior changed. + +- **What:** document a resume-channel redirect. A finished one-shot worker + leaves its session saved on disk, so a follow-up command can run one bounded + turn into that same session and exit. A /steer-prefixed follow-up is accepted + as instruction text. Follow-ups are scoped read-only unless the turn owns + files. Attaching to a session whose worker is still alive is prohibited. + +- **Why it changed:** without a defined channel, a correction after a finished + run meant starting a new session, which duplicated context, or attaching to a + session that might still be running, which risked two live writers on one + receipt boundary. One documented command closes the gap. + +- **Evidence:** [VERIFIED, internal operating record] mechanism and scope were + verified on a completed session on 2026-09-14 (internal QA record, + E-PROTEUS-008). The steering block is patched into the subagent-spawning + skill as the procedure's home. + +--- + +## 1.6.0 — Verification, evidence, and release gates (2026-09-14) + +- **What:** add a deterministic release gate runner at `build/verify-all.py` + that runs all public gates in documented order: sweep-gate, review-gate, + surface-scan, check-artifact-contract self-test, preflight/check self-test, + report/check self-test, and fresh-clone generation test. Also add GitHub + Actions workflow at `.github/workflows/verify.yml` that runs the gates on + push and pull requests with Python 3.11 and 3.12, using only checkout and + setup-python actions (safe for forks, no secrets). Fix a blind spot in + surface-scan: when `build/identifiers.yaml` is absent or empty, the scanner + still enforces built-in generic safety terms (paths, credential patterns) + that must never appear in public code. Add tests for verify-all and the + empty-identifiers case. Update README.md and index.html to document the + release gates and CI status. + +- **Why it changed:** need a single point of entry for verification that runs + all gates automatically, with CI integration that catches problems before + merge. The empty-identifiers fix ensures the scanner remains effective in + fresh clones and open-kit scenarios. + +- **Evidence:** [VERIFIED — internal operating record] gates, checkers, and + self-tests exist and pass; workflow tested on local execution. + +- **Files:** `build/verify-all.py`, `.github/workflows/verify.yml`, + `build/surface-scan.py`, `tests/test_gates.py`, `README.md`, `index.html`. +### Contract-validator gate integration (2026-09-14) + +- **What:** wires the kit's contract validators into the fresh-clone gate. + A new aggregator script (`build/check-contracts.py`) runs four validators + in sequence: artifact-contract validator (`--self-test`, `--example-check`), + preflight validator (`--selftest`), and report validator (`--selftest`). + The fresh-clone script (`scripts/fresh-clone-test.sh`) now includes this + as step 5, validating that the working tree's contract validators are + operational. All validators are stdlib-only, require no network or + credentials, and fail closed on errors. +- **Why:** Ensures the contract validation gates are always exercised as part + of the reproducible fresh-clone test, catching regressions in validator + logic before deployment. The gate validates the working tree; clone + reproducibility remains steps 1–4. +- **Evidence:** [VERIFIED — internal operating record] The validators are + already tested and proven in the fleet. Integration into the fresh-clone + gate makes this a standard, automated checkpoint. +- **Proof status:** [VERIFIED — internal operating record] Self-tests pass + locally; the fresh-clone gate completes with step 5 enabled. +- **Files:** `build/check-contracts.py`, `scripts/fresh-clone-test.sh`, + `README.md`, `index.html`. + +--- + +### Execution-evidence contract (2026-09-13) + +- **What:** adds `choreography/run-evidence.md`, defining a vendor-neutral + contract for recording execution evidence: what an agent actually executed, + not only that a procedure ran. Evidence record fields include run id, phase, + parent/child relations, step kind, tool/model identifiers, timestamps, status, + artifact references, unresolved items, and evidence boundary. Distinguishes + procedure evidence from achieved-state evidence (exit code alone insufficient). + Token accounting counts only innermost spans; cost honesty uses dated price + table (unknown models remain unknown); run comparison uses stable step keys + (kind + tool/name); retention is bounded with dropped-count visibility; no + secrets/raw prompts by default; local/loopback guidance. Includes acceptance + checklist and vendor-neutral example record. +- **Why:** Team6 has read-back receipts and logs but no local, framework-agnostic + artifact of what the agent actually executed (span tree, tool calls, tokens, + latency, per-model cost) nor a way to diff two runs step-by-step. This is the + one genuine capability gap identified in the local-agent-toolkit audit. +- **Evidence:** [VERIFIED — internal operating record] local-agent-toolkit audit + (2026-09-13) identifies observability as the one real gap. This release + implements the rules-only adaptation (no external code copied). + +- **Files:** `choreography/run-evidence.md`, `README.md`, `index.html`, `CHANGELOG.md`. + +--- + +### OpenShorts route (2026-09-14) + +- **What:** docs-only OpenShorts route + non-executable example config; no new dependencies; no bundled code; external tool license and dependency terms apply. +- **Files:** `choreography/openshorts-route.md`, `registry/openshorts-route.yaml.example`, README, CHANGELOG, index.html. + +### Safe shareable run packet (2026-09-13) + +- **What:** add a general safe shareable run packet: `choreography/safe-run-packet.md` + (required fields for objective, decisions, verified evidence, unresolved items, + changed artifacts, test results, runtime/live status, next gate, provenance, and + redaction status; a placeholder convention; and a shareable-surface safety rule) + and `build/report/check.py`, a standard-library-only validator with valid and + invalid fixtures that fails closed on a missing required field, evidence marked + verified without evidence, a live/staged status without target or evidence, + omitted unresolved items, an internal local path or profile path, a + credential-like value, or a placeholder outside the repository convention. The + generator seam is left untouched in this slice; the authored files ship through + the same authored-fresh mechanism when registered. +- **Why it changed:** a finished run must produce one artifact a second person can + read and share — what was attempted, what was decided, what is actually + verified, what is still open, what changed, how it was tested, whether anything + reached a live surface, and what happens next — without leaking an internal path, + a profile identity, or a credential value. +- **Evidence:** [VERIFIED — public conceptual source] the general idea of an + Agency Orchestrator-style run report, adopted as a concept. This is a + conceptual operating pattern, **not copied Agency Orchestrator code**: no + source, prompt, or dependency from any orchestrator project is bundled. The + Team6 Kanban board remains the authoritative task record; the packet is a + derived shareable report, not a second state store, and adds no runtime + integration, provider call, or configuration change. +- **Proof status:** [PROPOSED / PENDING] documentation contract plus local + validator; independent review required before treating it as release policy. +- **Files:** `choreography/safe-run-packet.md`, `build/report/` (README, checker, + fixtures), `README.md`, `CHANGELOG.md`. + +### Goal-state evidence guidance (2026-09-13) + +- **What:** add one operating rule to `choreography/artifact-contract.md`: + evidence must prove the achieved target state, not merely that a command or + procedure ran. A verifier rejects procedure-only evidence. +- **Why it changed:** a passing command does not prove the requested state was + reached. Adjudicating a handoff on procedure execution alone lets an + unachieved target state through. +- **Evidence:** [VERIFIED — public conceptual source] the state-versus-procedure + framing is inspired by Levin, M., "Ingressing Minds: Causal, Non-Physical + Patterns In-Form Natural, Synthetic, and Hybrid Embodiments," Philosophies + 11(5), 161 (2026), https://doi.org/10.3390/philosophies11050161. Adopted as a + framing for evidence sufficiency only. The paper's metaphysical and ontology + claims are not adopted, cited, or relied on. +- **Proof status:** [PROPOSED / PENDING] documentation rule; repository gates + and independent review required before release. +- **Files:** `choreography/artifact-contract.md`, `CHANGELOG.md`. + +### I/O delegation contract (2026-09-13) + +- **What:** add a public, vendor-neutral `choreography/io-delegation.md` + contract and `registry/io-delegation.yaml.example` example config. It + documents a bounded routing pattern for two narrow work classes — predictable + read-heavy summarization and pattern-conforming scaffolding — while the + frontier agent keeps edits, debugging, architecture, security/safety-critical + work, ambiguous requirements, and final acceptance. Route identity reuses the + provider/model/API-host rules in `choreography/model-policy.md`; input must + pass the local privacy/redaction policy in + `choreography/local-preprocessing.md` first; default mode is `observe` with no + invented quotas; worker output is advisory and ephemeral; and every delegation + records route, input/output byte counts, latency, status, fallback, and + verification result without raw sensitive content. Documentation and an + example config only — no executable hooks, network clients, model + dependencies, or profile-specific settings are added. +- **Why it changed:** a large-file offload pattern can reduce frontier-context + cost, but it carries real risks (sensitive-data leak, context loss, latency, + shallow summaries). The counterargument is met by making it an **opt-in, + bounded, audited contract** that is never automatic merely because a file is + large and never delegates the work that must stay on the frontier agent. +- **Evidence:** [VERIFIED — public conceptual source] Spotify Engineering + article "Portal by Spotify cut my Claude Code token usage by 90%" + (engineering.atspotify.com, 2026-09-03) describing a routing principle that + keeps frontier reasoning for edits/debugging/architecture/safety-critical + work and routes predictable I/O-heavy work to a cheaper worker. Adopted as a + principle only — no code, prompts, or source copied; the linked `shunt` + plugin is Apache-2.0 at `spotify/portal-ai-plugins@main/plugins/shunt` but is + referenced for the routing principle, not imported. The 90% figure is a + **self-reported vendor claim**, not Team6 evidence: Team6 adopts only the + routing principle and does not claim this result. +- **Proof status:** [PROPOSED / PENDING] Team6-kit documentation change; + fresh-clone gates and independent review required before release. +- **Files:** `choreography/io-delegation.md`, `registry/io-delegation.yaml.example`, + and the README overview. + +### Side-effect and cost preflight (2026-09-13) + +- **What:** add a general side-effect and cost preflight: `choreography/side-effect-cost-preflight.md` + (required fields for operation identity, files changed, external systems, credential + names only, paid operations, estimated quantity/cost units, conditional `may_run` + actions, public surfaces, bounded rollback, owner/approval state, explicit unknowns) + and `build/preflight/check.py`, a standard-library-only validator with valid and + invalid fixtures that fails closed on missing required fields, credential values, + unbounded waits, or missing rollback for side-effecting operations. The generator + ships these authored public files through its authored-fresh mechanism (verbatim + copy, no manifest row, no placeholder substitution; the audit count closes against + disk). +- **Why it changed:** an operation with side effects needs one reviewable + description before it runs: what it touches, what it spends, and how to undo + it. Unknown cost stays explicit and conservative; quotas are never invented. +- **Evidence:** [Internal design] Team6's own conceptual operating pattern for + side-effect and cost preflight. No external code, prompt, or dependency is + bundled. The Team6 Kanban board remains the authoritative task record; the + preflight is a review aid, not a runtime integration, and adds no provider + call, paid operation, or configuration change. +- **Proof status:** [PROPOSED / PENDING] documentation contract plus local + validator; independent review required before treating it as release policy. +- **Files:** `choreography/side-effect-cost-preflight.md`, + `build/preflight/` (README, checker, fixtures), `build/generate.py`, + `README.md`, `CHANGELOG.md`. + +### AI-assisted development contract (2026-09-13) + +- **What:** add a tool-neutral contract for AI-assisted changes: explicit scope + and acceptance criteria, behavior-first boundary/error testing, + security-sensitive checks, isolated parallel work, and independent evidence + read-back. +- **Why:** the public `jnMetaCode/ai-coding-guide` offers useful methods and + templates, but Team6 needs a smaller contract that preserves its existing + ownership, no-secret, QA, and verification rules. The source is used for + conceptual guidance only; no external template or executable surface is + bundled. +- **Evidence:** [VERIFIED — public conceptual source] `jnMetaCode/ai-coding-guide`, + snapshot `c5dde338c68adaac6cffc70ab11f1b1b22e70b0f`; adapted and reviewed in + PR #5 (see [LICENSING.md → AI-assisted development contract boundary](LICENSING.md#ai-assisted-development-contract-boundary-unreleased-2026-09-13)). + Root source license is Apache-2.0; the source's `book/` content is separately + identified as CC BY-NC-SA 4.0 and is not used. +- **Files:** `choreography/ai-assisted-development.md` and the README overview. + +## 1.5.0 — Artifact contract and resume/feedback handoff (2026-09-13) + +### Machine-checkable handoff contracts + +- **What:** add a generic handoff-contract format and its dependency-free + validator. One file per stage boundary carries: expected artifacts, + required sections/markers, size bounds, tests/commands, evidence refs, + runtime state (`local` / `staged` / `live`), explicit failure state, last + stable phase, resume phase, feedback to apply, artifacts to regenerate, and + artifacts **not** to touch. Ships as `choreography/artifact-contract.md` + (format + rules), `templates/contracts/artifact-contract.md.tmpl` (fill-in + template), `build/check-artifact-contract.py` (validator + 16-case + self-test), and valid/invalid examples in `examples/`. The generator ships + all five under `contracts/` in the instantiated kit. No second orchestration + runtime is added: the checker validates the *document*, never executes a + pipeline. +- **Why it changed:** resumed and review-cycle handoffs kept failing at the + artifact level even though `orchestration.md` §6/§7/§11 already demand + durable state, read-back receipts, and producer-committed signals — + finished work got redone, approved artifacts got silently rewritten, and + "done" claims carried no machine-checkable evidence. The missing piece was + a *checked* format, not another stated norm. +- **Provenance:** this is a Team6 internal operating record for artifact + handoffs. The pattern was designed by Team6 to solve resume/feedback + boundary issues in Kanban workflows; it is not derived from external code + or documentation, and no external orchestration code, prompts, or prose + are bundled. The field set, parser, and rules are Team6's own generic + form. **Team6 Kanban remains the state authority** — the contract is a + per-handoff snapshot written out of the Kanban record, never a + replacement for it. +- **Evidence:** [VERIFIED — internal operating record] the fleet's + resume/handoff failure classes (read-then-die, STABLE-marker deadlock, + silent rewrites — see the 1.1.0 item 13 record). [VERIFIED] the checker's + self-test: 16/16 pass, including a missing-required-field case that fails + and a complete contract that passes, and both repo examples validate to + their expected verdicts (valid → exit 0, invalid → exit 1 for the + missing `resume_phase` and the illegal `runtime_state` enum). Public files + contain generic names only; the full 8-surface leak scan passes. +- **Files:** `choreography/artifact-contract.md`, + `templates/contracts/artifact-contract.md.tmpl`, + `build/check-artifact-contract.py`, `build/generate.py` (contracts/ copy + step), `examples/artifact-contract.{valid,invalid}.yaml`, README, CHANGELOG. + +--- + +## 1.4.1 — Router trust-boundary and tool-execution safety (2026-09-13) + +- **What:** add `choreography/router-security.md`, a vendor-neutral preflight + contract for model routers and relays. It covers endpoint and upstream-path + trust, credential minimization, high-risk tool gates, autonomous execution, + metadata-only audit logs, and conditional or dependency-targeted tampering + tests. It provides a generic checklist for evaluating whether a router or + relay meets the team's safety requirements before it is enabled. +- **Why it changed:** routers and relays can see plaintext requests and + responses, and may sit between a model provider and the tools an agent runs. + Without a trust boundary, there is no shared checklist for endpoint trust, + credential handling, high-risk tool gates, autonomous execution, audit + logging, or tampering tests. The new contract provides one. +- **Evidence:** [Internal design] Team6's own conceptual operating pattern for + router trust boundaries. No external code, prompt, or dependency is + bundled. The Team6 Kanban board remains the authoritative task record; the + contract is a review aid, not a runtime integration, and adds no provider + call, paid operation, or configuration change. +- **Proof status:** [PROPOSED / PENDING] documentation contract plus local + validator; independent review required before treating it as release policy. +- **Files:** `choreography/router-security.md` and the README overview. + +## 1.4.0 — Dynamic model-policy catalogue (2026-09-13) + +### Route-based rate-limit protection + +- **What:** add a route-based model-policy catalogue (registry/model-rate-limits.yaml.example + and choreography/model-policy.md) for tracking provider limits per model, + API host, and provider. It supports bounded admission, protected reserves, + and observe-only mode for unknown limits. +- **Why it changed:** models move between agents, tasks, and workers. Without + a unified policy, the team risks hitting unknown limits or inventing quotas. + A route-based policy that follows the model by provider, identifier, and host + solves this. +- **Evidence:** [Internal design] Team6's own conceptual operating pattern. No + external code, prompt, or dependency is bundled. The Team6 Kanban board + remains the authoritative task record. +- **Files:** `registry/model-rate-limits.yaml.example`, `choreography/model-policy.md`, + and the README overview. + +## 1.3.0 — Handover ingestion completeness & propagation loop (2026-09-12) + +**Convention note:** The audit artifacts named by the original 1.3.0 record are not present in the current tree. The entries below preserve the conceptual history of that release; no current path is asserted for those historical files. + +### 1. A handed-over source is not reference-only until it is audited + +- **What:** a source handed over from another team or external party must go + through a structured audit: ownership review, capability matrix, disposition + classification, surface validation, and propagation through each surface's + own gate. +- **Why:** without a structured audit, handed-over sources accumulate + unclassified references, duplicate content, or orphan surfaces that never + propagate to the full surface set. +- **Evidence:** [Internal design] Team6's own operating procedure from real + handovers (the original 1.3.0 audit trail is not carried in this tree; see the convention note above). + +### 2. The audit inspects surfaces, not the README + +- **What:** the audit inspects the full surface set (README, CHANGELOG, registry, + templates, choreography) and validates each against the candidate. It does + not rely on README references alone. +- **Why:** references in the README do not guarantee the full surface set is + complete or correct. +- **Evidence:** [Internal design] Team6's own operating procedure. + +### 3. Capability matrix, owner, and disposition + +- **What:** each handed-over candidate gets a capability matrix (what it covers, + what it omits), an owner (who is responsible for it), and a disposition + (adopt, adopt with caveats, or discard). +- **Why:** without these, candidates accumulate without clear ownership or + disposition. +- **Evidence:** [Internal design] Team6's own operating procedure. + +### 4. Separate the five phases + +- **What:** handover audits follow five phases: intake, capability matrix, + disposition, surface validation, and propagation. Each phase is recorded + in the handover audit file. +- **Why:** separating phases makes handovers auditable and reproducible. +- **Evidence:** [Internal design] Team6's own operating procedure. + +### 5. Bounded proof, receipts, and read-back + +- **What:** each phase produces bounded proof (audit artifacts, surface + inventory, propagation receipts) and requires a read-back to validate + that the candidate is understood and correctly applied. +- **Why:** without proof and read-back, handovers are opaque and error-prone. +- **Evidence:** [Internal design] Team6's own operating procedure. + +### 6. Preserve unresolved, dead, and blocked + +- **What:** the audit preserves unresolved items, dead candidates, and blocked + work in the handover record, with disposition and owner for each. +- **Why:** without preservation, candidates lose context and accumulate without + resolution. +- **Evidence:** [Internal design] Team6's own operating procedure. + +### 7. Propagation through each surface's own gate + +- **What:** validated content propagates through each surface's own gate (README, + CHANGELOG, registry, templates, choreography) and each gate is recorded in + the handover audit. +- **Why:** without gate-by-gate propagation, content accumulates without + consistency across surfaces. +- **Evidence:** [Internal design] Team6's own operating procedure. + +### 8. One capability delta per candidate, routed by impact class + +- **What:** each candidate produces one capability delta (what changes) routed + by impact class (documentation, configuration, or code). Each delta is + reviewed and signed off separately. +- **Why:** without routing by impact class, deltas accumulate without + consistent review. +- **Evidence:** [Internal design] Team6's own operating procedure. + +--- + +## 1.2.0 — Desert Ant local preprocessing (2026-09-11) + +- **What:** add `choreography/local-preprocessing.md` (Desert Ant reference + architecture for local privacy/redaction). This is guidance only. +- **Why:** agent inputs can leak sensitive content or cost-inefficient data. + Local preprocessing (redaction, cost filters, content pruning) protects + privacy and cost before they reach an external provider. +- **Evidence:** [VERIFIED — public conceptual source] Desert Ant reference + architecture (desert-ant/desert-ant repo, Apache-2.0). Used for concept only; + no code, prompt, or dependency is bundled. +- **Files:** `choreography/local-preprocessing.md`. + +## 1.1.0 — Local privacy/redaction policy (2026-09-10) + +- **What:** add `choreography/local-preprocessing.md` (local privacy/redaction + policy). This is guidance only — no runtime or dependency is added. +- **Why:** agent inputs can leak sensitive content or cost-inefficient data. + Local preprocessing (redaction, cost filters, content pruning) protects + privacy and cost before they reach an external provider. +- **Evidence:** [Internal design] Team6's own conceptual operating pattern. +- **Files:** `choreography/local-preprocessing.md`. + +--- + +## 1.0.0 — Initial release (2026-09-01) + +- **What:** initial release of Team6-kit, a framework for turning a single AI + agent engine into a multi-agent team with clear rules and responsibilities. +- **Why:** to provide a reference implementation for multi-agent team + orchestration with clear contracts, QA gates, and provenance tracking. +- **Evidence:** [Internal design] Team6's own conceptual operating pattern. +- **Files:** Initial commit. diff --git a/LICENSING.md b/LICENSING.md index f0ad693..2e5986c 100644 --- a/LICENSING.md +++ b/LICENSING.md @@ -1,19 +1,35 @@ -# Licensing — Protean Kit +# Licensing — the Protean Kit distribution -This repo is a STANDALONE product built on the Hermes engine. It is not a -git-fork of Hermes: no upstream source or history is copied into this tree. +This repository is the distribution home of the Protean Kit. It is a +STANDALONE product built on the Hermes engine. It is not a git-fork of Hermes: +no upstream source or history is copied into this tree. -The two-zone license claim rests on this document + the README, not on a -git-history boundary. Read this before contributing. +- **Source of truth:** `https://github.com/aska-digital/protean-kit`. +- The zone model below rests on this document and the README, not on a + git-history boundary. Read this before contributing. ## Zones +The zone model is the one in the table below. Where a repository ships its own +committed `LICENSE` file, that file is authoritative for that repository. + | Zone | Paths | License | Notes | |---|---|---|---| | Engine-derived | `build/` tooling (scanner, gates, generator, manifest), generic skills under `templates/skills/` | **MIT — provenance today, obligation on arrival** | The repo's current content is entirely our own authored work (Apache-2.0). The MIT zone is a FORWARD CONTRACT: MIT attaches when engine-derived code actually lands here (the setup-agent PR, any vendored tooling). Today there are no MIT files in this tree; the zone names what the future upstream surface will be. Nothing here carries instance data. | -| Kit layer | `choreography/`, `templates/personas/`, `registry/kit.yaml`, `AUDIT/` | **Apache-2.0** | Our identity archetypes, orchestration contract, governance, and build evidence. | +| Composer layer | `kit.lock.json`, `install.sh`, `build/check-lock.py`, `build/check-ingredient-contract.py`, `choreography/`, `templates/personas/`, `registry/kit.yaml`, `AUDIT/` | **Apache-2.0** | The composition manifest, the installer, the composition gates, the identity archetypes, the orchestration contract, governance, and build evidence. | +| Ingredient layer | not in this repository | **MIT, per ingredient** | The ingredients the manifest pins are separate repositories. Each one commits its own `LICENSE` file, which is authoritative for it. This repository holds no ingredient payload: composition is manifest-only. | | Proprietary | `registry/packs/` parameter files | **Proprietary by contract** | Vertical packs are service deliverables — NEVER committed to this repo. The `packs/README.md` shape is public; the parameter files are not. | -| Product brand | `README.md`, `LICENSE` | Apache-2.0 (README), Apache-2.0 (LICENSE) | The product name `Protean Kit` is our brand. | +| Product brand | `README.md`, `LICENSE` | Apache-2.0 (README), Apache-2.0 (LICENSE) | The product name is the distribution's brand. | + +## Composition and pinning (lock version 1) + +The distribution pins each ingredient by annotated tag plus peeled commit SHA +and a tree hash (`protean-tree-v1`). A pin is immutable: a moved tag is an +integrity failure, never a silent upgrade, and the only legal change to a lock is +a new tag or a `lockVersion` bump. The installer verifies the pin, installs into +a staging directory, promotes an ingredient only after its own gates pass, and +then re-hashes every written file against the cached blob. Ingredient licenses +are declared per ingredient and enforced by the ingredient-contract gate. ## Rules @@ -95,7 +111,7 @@ the boundary is explicit: v1.2.0 adopts the canonical-site decision for the Protean Team site: - **Canonical public site:** `https://proteus.askaconsult.com/`. -- **Repository/source of truth:** `https://github.com/Protean-Group/protean-kit`. +- **Repository/source of truth:** `https://github.com/aska-digital/protean-kit`. - **GitHub Pages:** not used. The old Pages site was taken down. - **Deployment boundary:** the canonical site is served by the ASKA-managed Protean Team deployment; DNS and deployment settings are outside this repo. @@ -105,6 +121,6 @@ v1.2.0 adopts the canonical-site decision for the Protean Team site: ## Provenance - Engine: Hermes by Nous Research — MIT (https://github.com/NousResearch/hermes-agent) -- This repo: `Protean Kit` — Apache-2.0 core + proprietary packs by contract +- This repo: the Protean Kit distribution (`aska-digital/protean-kit`) — Apache-2.0 composer layer + proprietary packs by contract; pinned ingredients are MIT under their own committed LICENSE files - `AUDIT/fork-commit-1.md` — the first commit's cleanliness evidence (surface scan, staged-tree manifest, invariant check, verification lineage) diff --git a/README.md b/README.md index 4c8c7bf..a463965 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ During an orchestration test, a stale branch 14 commits behind origin/main was u [VERIFIED — internal operating record] Grounded in the team's shared doctrine and dated session history. +Source of truth: https://github.com/aska-digital/protean-kit + ## What problem does it solve? One AI agent can lose track, skip steps, or claim work is done when it isn't. Protean Kit sets up several agents with separate jobs — planner, builder, checker — and rules so that: @@ -197,6 +199,148 @@ and establishes rules for token accounting (innermost spans only), cost honesty bounded retention with no secrets or raw prompts by default. Read `choreography/run-evidence.md`. +## The Protean Kit distribution (lock version 1) + +This repository is also the composer of the Protean Kit: it pins six standalone +ingredients, and one command installs the whole set. + +``` +bash install.sh --all --target ./protean-installed +``` + +Preview the plan first. The composer supports `--dry-run`; it prints the +selection, the resolved install order, the target, the network mode, and the +planned writes, and it writes nothing. + +``` +bash install.sh --all --target ./protean-installed --dry-run +``` + +The composer holds the lock, the installer, the documentation, and the gates. It +**contains no ingredient payload and no submodule**: composition is manifest-only. +Each ingredient is fetched from its pinned tag, verified against the tag's peeled +commit SHA and its tree hash, installed, and then read back file by file. + +### Ingredients + +| slug | one-line contract | requires | recommends | installs to | +|---|---|---|---|---| +| `protean-doctrine` | The operating doctrine: the default pipeline, role delegation map, handoff protocol, QA gates, and external-writing discipline. | none | none | `skills/protean-operating-doctrine`, `skills/external-writing-discipline`, `gates/protean-doctrine` | +| `protean-ops` | The dispatch/rotation/inflight ops kit: append-only record schemas and the deterministic gates that check them. | none | none | `records`, `scripts/protean-ops`, `gates/protean-ops` | +| `protean-sym2p` | SYM-2P: a compact versioned agentic message language - one canonical JSON packet per line over durable text artifacts - with validator, enums, and fixtures. | none | `protean-ops` | `SPEC.md`, `skills/sym2p`, `scripts/protean-sym2p`, `templates/protean-sym2p`, `examples/protean-sym2p`, `AUDIT/protean-sym2p`, `gates/protean-sym2p` | +| `protean-drafts` | The draft-review pipeline: render a draft as a self-contained dark HTML review page through one command that runs the prose, identifier, quote-integrity, and render-fidelity gates. | none | `protean-doctrine` | `skills/draft-review-html`, `scripts/protean-drafts`, `templates/protean-drafts`, `gates/protean-drafts` | +| `protean-github-flow` | The GitHub workflow skill pack: issue triage, issue-to-PR, PR lifecycle, PR audit, and upstream-contribution procedures. | none | `protean-drafts`, `protean-doctrine` | `skills/github-issues`, `skills/github-issue-to-pr`, `skills/github-pr-workflow`, `skills/github-pr-audit`, `skills/upstream-contribution-pr`, `gates/protean-github-flow` | +| `protean-control-plane` | The control-plane skill pack: one canonical procedure home that routes a request to the minimum skill bundle, with the gate table and failure policy. | `protean-doctrine`, `protean-ops` | `protean-drafts`, `protean-github-flow`, `protean-sym2p` | `skills/protean-control-plane`, `gates/protean-control-plane` | + +The exact install targets, the pinned SHA, and the tree hash of each ingredient +are recorded in `kit.lock.json`, which is authoritative. + +### Dependency behaviour + +Two edge kinds exist. `requires` is hard: the closure is fetched and installed. +`recommends` is soft: it is reported and never fetched. + +The lock declares the install order in `installOrder`, and the resolver validates +that declaration against the dependency graph before it is used. A declaration +that is not a valid topological order of the selection is reported, and the +resolver's own topological order is used instead. A `requires` cycle is a hard +failure with the cycle path printed, and it is never resolved by dropping an +edge. + +Only `protean-control-plane` declares `requires` edges, on `protean-doctrine` and +`protean-ops`. Every other edge in the version 1 set is `recommends`. + +``` +bash install.sh --ingredient protean-drafts --target ./protean-installed +``` + +`protean-drafts` has no hard requirements, so exactly one repository is fetched +and written. The full kit is not touched and not fetched. + +``` +bash install.sh --ingredient protean-control-plane --target ./protean-installed +``` + +`protean-control-plane` resolves to exactly three repositories: doctrine, ops, and +itself. Its skill cites the record gates, so it declares the dependency instead of +copying the files. + +``` +bash install.sh --ingredient protean-control-plane --no-deps --target ./protean-installed +``` + +`--no-deps` is a deliberate degraded mode. It writes exactly one repository and +reports the unresolved requirements as `degraded`, and the control plane reports +its cited gates as `unavailable` instead of failing for it. The control plane is +not fully operational in that mode, and the summary says so. + +### Offline and cache + +The cache is content-addressed by commit SHA: `///`, where the +cache root is `$PROTEAN_CACHE`, else `${XDG_CACHE_HOME:-$HOME/.cache}/protean-kit`. +A cache entry is immutable while it matches its SHA, and the same SHA is never +fetched twice. + +``` +bash install.sh --all --target ./protean-installed --offline +``` + +`--offline` makes zero network calls and installs from the cache only. A missing +or mismatched entry fails closed with exit 4, naming the slug. A warm cache run +with `--offline` is the way to prove an install needs no network. + +### Target, staging, and read-back + +The default target is `$HERMES_TEAM_SKILLS` when that is set, else `./installed`; +public instructions pass `--target` explicitly so the write boundary is visible. +Writes are staged under `/.protean-staging//` and promoted only +after that ingredient's own gates pass, so a mid-run failure leaves no half +written ingredient on the target. Every written file is then re-hashed against +its cached blob. + +### Troubleshooting + +The exit code is the reliable signal for automation. Errors go to stderr, the +summary to stdout. + +| Exit | Meaning | Recovery | +|---|---|---| +| `1` | usage or input is invalid | Correct the flag or the slug, and read `--help`. | +| `2` | the kit lock is invalid | Use a valid lock. Do not bypass the allowlist, the tag rule, or the schema check. | +| `3` | dependency resolution failed | Repair the lock, or use `--no-deps` only when degraded operation is acceptable. | +| `4` | integrity check failed | Refresh the cache in online mode from the pinned ref, or restore a matching warm cache. Never substitute another SHA. | +| `5` | install failed | Fix the target permissions or the ingredient defect. The run is not successful. | +| `6` | post-install verification failed | Understand the mismatch, then rerun. The target holds an incomplete install, and the summary reports it. | + +A run that installs five of six ingredients exits non-zero. There is no partial +success zero. + +### Verify this release + +``` +python3 build/check-lock.py kit.lock.json --verify +python3 build/check-ingredient-contract.py --lock kit.lock.json --verify +python3 -m unittest tests.test_kit_lock +``` + +`check-lock.py` validates the lock and, with `--verify`, recomputes every pin's +tag pairing and tree hash. `check-ingredient-contract.py` checks each pinned +ingredient at its pinned commit for `README.md`, a committed `LICENSE`, its +descriptor, its entrypoint, its declared gates, and a non-empty `tests/`. Without +a warm cache or a sibling checkout, both gates report the pins as unverified +rather than inventing a result. + +### Limits and open items + +- The ingredient repositories ship under the MIT license. Each commits its own + `LICENSE` file, which is authoritative for that repository. +- The version 1 set pins six ingredients. Whether every one of them belongs in + version 1 is an open item recorded by the project, not a decision made here. +- The protocol ingredient carries its own open items; the installer reports them + in its summary and never resolves them. +- The composer's own brand strings and the site registry still name the + predecessor product; that rename is a user decision, not a packaging change. + ## The main rules 1. **Everything on disk.** Progress is saved to files, so months later you can still pick up where you left off. @@ -221,7 +365,9 @@ The kit now includes a route-based model-policy catalogue for changing provider - **Engine:** Hermes by Nous Research, MIT license. This is not a fork; we build on top of it. - **This kit (profiles, rules, builder):** Apache-2.0. +- **Pinned ingredients (lock version 1):** MIT, each under its own committed `LICENSE` file. - **Vertical packs (paid settings files + service):** not in this repo; proprietary. - Optional local models used by an adapter have their own separate license. -Full details: `LICENSING.md`. +Licensing follows the zone model in `LICENSING.md`; the committed `LICENSE` file +in each repository is authoritative for that repository. diff --git a/build/verify-all.py b/build/verify-all.py new file mode 100644 index 0000000..aee1049 --- /dev/null +++ b/build/verify-all.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python3 +""" +verify-all.py — Deterministic release gate runner. + +Runs the repository's public gates in documented order. Uses subprocess with +fail-closed behavior: nonzero exit on any failure. No dependencies beyond stdlib. + +ORDER (this list is the gate list; the composer holds no separate release-gates +document, and this docstring is authoritative): + 1. sweep-gate.py — extraction source verification + 2. review-gate.py — semantic sign-off enforcement + 3. surface-scan.py — multi-surface leak detector + 4. check-artifact-contract.py self-test + 5. preflight/check.py self-test + 6. report/check.py self-test + 7. composition lock validity (check-lock.py, static) + 8. ingredient contract (check-ingredient-contract.py, static) + 9. composition lock tests (tests/test_kit_lock.py) + 10. fresh-clone test (generate.py fork-dryrun check) + +Exit: 0 = all gates pass; 1 = any gate failed. +""" + +import os +import subprocess +import sys + +HERE = os.path.dirname(os.path.abspath(__file__)) +ROOT = os.path.dirname(HERE) + + +def run_gate(name, cmd, cwd=ROOT): + """Run a gate, print its output, return True on pass.""" + print(f"\n{'=' * 64}") + print(f"STEP: {name}") + print('=' * 64) + + try: + result = subprocess.run( + cmd, + capture_output=True, + text=True, + cwd=cwd, + timeout=300 # 5 minute timeout per gate + ) + + # Print stdout (the gate's own output) + if result.stdout: + print(result.stdout) + + # Print stderr if present (warnings, notes) + if result.stderr: + print(result.stderr, file=sys.stderr) + + if result.returncode == 0: + print(f"\n✓ {name}: PASSED") + return True + else: + print(f"\n✗ {name}: FAILED (exit {result.returncode})") + return False + + except subprocess.TimeoutExpired: + print(f"\n✗ {name}: TIMEOUT") + return False + except Exception as e: + print(f"\n✗ {name}: ERROR — {e}") + return False + + +def main(): + print("=" * 64) + print("TEAM6-KIT RELEASE GATE RUNNER") + print("=" * 64) + print("\nThis runner executes all public release gates in documented order.") + print("Any failure stops execution. All gates use fail-closed semantics.") + + gates = [] + + # 1. sweep-gate + gates.append(("sweep-gate.py", [sys.executable, os.path.join(HERE, "sweep-gate.py")])) + + # 2. review-gate + gates.append(("review-gate.py", [sys.executable, os.path.join(HERE, "review-gate.py")])) + + # 3. surface-scan + gates.append(("surface-scan.py", [sys.executable, os.path.join(HERE, "surface-scan.py")])) + + # 4. check-artifact-contract self-test + gates.append(("check-artifact-contract self-test", + [sys.executable, os.path.join(HERE, "check-artifact-contract.py"), "--self-test"])) + + # 5. preflight/check.py self-test + gates.append(("preflight/check self-test", + [sys.executable, os.path.join(HERE, "preflight", "check.py"), "--selftest"])) + + # 6. report/check.py self-test + gates.append(("report/check self-test", + [sys.executable, os.path.join(HERE, "report", "check.py"), "--selftest"])) + + # 7. composition lock validity + gates.append(("check-lock.py", + [sys.executable, os.path.join(HERE, "check-lock.py"), + os.path.join(ROOT, "kit.lock.json")])) + + # 8. ingredient contract (reports pinned trees it cannot read, never invents one) + gates.append(("check-ingredient-contract.py", + [sys.executable, os.path.join(HERE, "check-ingredient-contract.py"), + "--lock", os.path.join(ROOT, "kit.lock.json")])) + + # 9. composition lock tests + gates.append(("composition lock tests", + [sys.executable, "-m", "unittest", "tests.test_kit_lock"])) + + # 10. fresh-clone test (fork-dryrun.sh) + fork_dryrun = os.path.join(HERE, "fork-dryrun.sh") + if os.path.isfile(fork_dryrun): + # Use current repo as source and 'main' as branch; no private paths. + gates.append(("fresh-clone fork-dryrun", + ["bash", fork_dryrun, ROOT, "main"])) + else: + # Alternative: verify generate.py works in fork mode + gates.append(("fresh-clone generate test", + [sys.executable, os.path.join(HERE, "generate.py"), "--help"])) + + # Run all gates + results = [] + for name, cmd in gates: + passed = run_gate(name, cmd) + results.append((name, passed)) + + # Summary + print("\n" + "=" * 64) + print("SUMMARY") + print("=" * 64) + + passed = sum(1 for _, p in results if p) + failed = sum(1 for _, p in results if not p) + total = len(results) + + print(f"\n Gates run: {total}") + print(f" Passed: {passed}") + print(f" Failed: {failed}") + + print("\n Results:") + for name, p in results: + status = "✓ PASS" if p else "✗ FAIL" + print(f" {status}: {name}") + + print("\n" + "=" * 64) + + if failed > 0: + print("RELEASE BLOCKED — one or more gates failed.") + print("Fix failures before proceeding.") + return 1 + else: + print("RELEASE GATES PASSED — safe to proceed.") + return 0 + + +if __name__ == "__main__": + sys.exit(main())