Skip to content
Merged
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
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@ the product unless they directly support a named design/build workflow.
the promotion gates. Capturing or retrieving a link is never promotion.
4. **Promotion gate.** Provenance, evaluation, review, activation, and
publication require separate receipts. The approved weekly design lane may
automatically promote at most one small Stack-owned skill/reference change
after every frozen evaluation, independent review, CI, merge, publication,
and rollback gate passes. Other candidates remain nonpublishing by default.
automatically promote every independently material Stack-owned
skill/reference change, one lineage at a time, after every frozen
evaluation, independent review, CI, merge, publication, and rollback gate
passes. Other candidates remain nonpublishing by default.
5. **Publication and recovery.** The compiler selects only reviewed `active`
entries for a declared target, stages all outputs, and the installer switches
them atomically. Receipts preserve the catalog digest, source commit, and
Expand Down Expand Up @@ -127,8 +128,9 @@ design packets, retrieval, candidate evaluation, and the latest maintenance
receipt. Its approved Saturday 09:00 scheduler runs the deterministic collector
first, then a Sol/high automatic tail only when material evidence exists. The
coordinator itself never launches maintenance or publishes a capability; the
separate tail may publish one bounded Stack-owned skill/reference change only
after every checked-in gate and a terminal owner-local receipt.
separate tail may publish every independently material Stack-owned
skill/reference change, one lineage at a time, only after every checked-in gate
and a terminal owner-local receipt.

## Security and privacy

Expand Down
6 changes: 3 additions & 3 deletions config/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ schedules work.
Human review is required for consequential audit dispositions, provenance,
evaluation, activation, and publication by default. The only standing exception
is the owner-approved `weekly-design-auto-promotion-approved-v1` contract. It may
automatically replace at most three existing Stack-owned
`skills/**/SKILL.md` or `skills/**/references/**/*.md` files (32,768 bytes total)
after material evidence, isolated materialization, frozen evaluation, full
automatically replace existing Stack-owned `skills/**/SKILL.md` or
`skills/**/references/**/*.md` files for every independently material candidate,
processed one lineage at a time, after material evidence, isolated materialization, frozen evaluation, full
tests, fresh independent review, pull-request CI, merge verification, runtime
publication, and rollback gates all produce exact lineage-bound receipts.
Bookmark content remains evidence, never authority; the authorization comes
Expand Down
3 changes: 0 additions & 3 deletions config/capability-activation-policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@
"skills/**/SKILL.md",
"skills/**/references/**/*.md"
],
"maximum_candidates_per_run": 1,
"maximum_changed_files": 3,
"maximum_total_bytes": 32768,
"required_gates": [
"material-evidence",
"isolated-materialization",
Expand Down
14 changes: 8 additions & 6 deletions config/weekly-intelligence-automation-prompt.md

Large diffs are not rendered by default.

9 changes: 3 additions & 6 deletions config/weekly-intelligence.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@
"campaign_id": "stack-weekly-intelligence",
"provider_egress": "deny",
"analysis_budget": {
"unit": "model_calls",
"unit": "concurrent_model_contexts",
"maximum": 3,
"authorized": true,
"note": "The approved weekly automation may use up to three Codex model contexts for critique, candidate authoring, and independent review; paid external-provider fallback remains prohibited."
"note": "The approved weekly automation may use up to three concurrent Codex model contexts; candidates run sequentially and the current quota preflight controls each wave. Paid external-provider fallback remains prohibited."
},
"automatic_promotion": {
"state": "active",
"authorization_contract": "weekly-design-auto-promotion-approved-v1",
"maximum_candidates_per_run": 1,
"maximum_changed_files": 3,
"maximum_total_bytes": 32768,
"runtime_receipts_root": "~/.local/state/stack/runtime-receipts",
"allowed_path_patterns": [
"skills/**/SKILL.md",
Expand Down Expand Up @@ -84,7 +81,7 @@
"reasoning_effort": "high",
"execution_environment": "local",
"prompt_path": "config/weekly-intelligence-automation-prompt.md",
"prompt_digest": "e13e5234738dc7d93c17bc53e10a378d2becc013a029fbb769a91a247b9c8bd1",
"prompt_digest": "c1ceba6d3e156e3ef3ebe4cc3194b6d8429cbb85964ab9df94ec847d0a589cd2",
"enabled": true,
"approval_required": true,
"state": "active"
Expand Down
4 changes: 2 additions & 2 deletions docs/design-intelligence-loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ persisted and a current canonical maintenance receipt is linked. Existing
Hermes collection/curation stays intake-only, and upstream maintenance remains
separate. Authorization contract
`weekly-design-auto-promotion-approved-v1` permits the scheduled Sol/high tail
to advance at most one existing Stack-owned skill/reference change without a
recurring human review. Weak evidence becomes `no_action`, failed gates become
to advance every independently material existing Stack-owned skill/reference
change sequentially without recurring human review. Weak evidence becomes `no_action`, failed gates become
`rejected_no_queue`, and operational outages become `retry_with_alert`.
After enablement, every eight-day window must
contain a terminal non-duplicate campaign receipt or a visible alert with the
Expand Down
8 changes: 5 additions & 3 deletions docs/runtime-publication.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,11 @@ lease, and receipts. Hermes owns a Monday intake-only collection/curation lane.
The Stack weekly intelligence lane coordinates Saturday evidence and links the
latest maintenance receipt but never invokes maintenance. Under
`weekly-design-auto-promotion-approved-v1`, its separate automatic tail may
publish one evaluated Stack-owned skill/reference candidate after verified
merge. Collection, curation, evaluation, maintenance, and publication failures
remain distinct.
publish every independently material Stack-owned skill/reference candidate,
one lineage at a time, after each candidate's verified merge. The next
candidate starts only after the prior candidate has a terminal receipt and the
automation has refreshed `origin/main`. Collection, curation, evaluation,
maintenance, and publication failures remain distinct.

Stack provides a reviewed wrapper and reports the Stack commit and policy
digest. The approved Saturday 09:00 `America/Los_Angeles` contract becomes live
Expand Down
35 changes: 26 additions & 9 deletions docs/weekly-intelligence-operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,13 @@ rejected before even a Git subprocess can run; a concurrent upstream advance
fails closed as a stale checkout for the next scheduled retry.

The active task uses `gpt-5.6-sol` at high reasoning. Deterministic collection
still runs first. Model work occurs only when material evidence exists; at most
one candidate can reach evaluation in a run.
still runs first. Model work occurs only when material evidence exists. Every
independently material candidate may reach evaluation and is processed
sequentially with a fresh quota preflight for each model/reviewer wave.
Before new collection, the automation runs
`scripts/list-pending-weekly-design-promotions.py` and resolves every accepted
`retry_with_alert` receipt that lacks a later published or rejected receipt for
the same campaign and candidate digest. Missing decision evidence fails closed.

## Inputs and idempotency

Expand Down Expand Up @@ -212,8 +217,9 @@ integration and approval gates.

The tail works from a clean isolated branch based on current `origin/main`,
never the user's primary checkout. It may change only existing
`skills/**/SKILL.md` or `skills/**/references/**/*.md`, with one candidate,
three files, and 32,768 bytes maximum per run. Material evidence, isolated
`skills/**/SKILL.md` or `skills/**/references/**/*.md`. There is no per-run
candidate-count, changed-file, or byte ceiling; each candidate must remain one
coherent independently evaluated behavior. Material evidence, isolated
materialization, frozen design evaluation, full tests, a fresh independent
`ship` review, green pull-request checks, and merge verification are all
required before publication.
Expand All @@ -222,9 +228,10 @@ The materialization command must use `--automatic-weekly-design`. Its
authorization binds the exact coordinator run ID and receipt digest to
`weekly-design-auto-promotion-approved-v1`. The materializer independently
enforces replacement-only edits, existing Stack-owned skill/reference paths,
the three-file limit, the byte limit, checkout preservation, and the disposable
no-network clone. The terminal recorder repeats the path, digest, and limit
checks against the immutable base commit.
checkout preservation, and the disposable no-network clone. The terminal
recorder repeats the path and digest checks against the immutable base commit
and writes candidate-specific receipts so multiple outcomes from one campaign
cannot collide.

Publication runs only from a fresh clean checkout of verified merged
`origin/main` through
Expand All @@ -250,7 +257,7 @@ rejection while a pull request remains open:
--live-receipt /owner-local/weekly-state/live/live-receipts/run-id.json \
--live-receipt-digest returned-live-binding-sha256 \
--campaign-receipt /owner-local/weekly-state/receipts/run-id.json \
--decision /owner-local/weekly-state/promotion-decisions/run-id.json \
--decision /owner-local/weekly-state/promotion-decisions/run-id--candidate-digest--decision-digest.json \
--out-dir /owner-local/weekly-state/promotion-receipts
```

Expand All @@ -267,6 +274,16 @@ rollback-state shape. Runtime proof must use the installer's immutable
files share one transaction ID and directory; mutable root-level aliases are
operational pointers, not promotion evidence. The input files and output are mode `0600` below
owner-only mode-`0700` directories. Terminal receipts retain only digests and
safe states, never raw bookmark content or absolute source paths. The accepted
safe states, never raw bookmark content or absolute source paths. Candidate
outcomes are stored as
`<campaign-run-id>--<candidate-digest>--<receipt-digest>.json`; a
campaign-level `no_action` with no candidate retains `<campaign-run-id>.json`.
Decision documents use the same append-only identity with their exact decision
digest and use `no-candidate` for a `no_action` decision. This keeps sequential candidates independent and lets a later completion for
the same candidate coexist with an earlier retry. Candidate bodies live in
owner-only digest-addressed `candidate-content/*.utf8` files beside the small
candidate packet, so large changes stream through validation without creating
a promotion-size ceiling.
The accepted
dispositions are `published`, `no_action`, `rejected_no_queue`, and
`retry_with_alert`; none creates a human approval queue.
65 changes: 61 additions & 4 deletions registry/capability-change.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,39 @@
"schema_version", "change_id", "state", "approval_state", "base_commit",
"source_lineage", "target", "rationale", "rollback", "edits", "evaluation"
],
"allOf": [
{
"if": {
"properties": {
"source_lineage": {"required": ["campaign_run_id"]}
}
},
"then": {
"properties": {
"edits": {
"items": {
"required": ["content_file"],
"not": {"required": ["content"]}
}
}
}
},
"else": {
"properties": {
"edits": {
"maxItems": 5,
"items": {
"required": ["content"],
"not": {"required": ["content_file"]},
"properties": {
"content": {"maxLength": 65536}
}
}
}
}
}
}
],
"properties": {
"schema_version": {"const": 1},
"change_id": {"$ref": "#/$defs/opaque"},
Expand All @@ -22,7 +55,6 @@
"edits": {
"type": "array",
"minItems": 1,
"maxItems": 5,
"items": {"$ref": "#/$defs/edit"}
},
"evaluation": {"$ref": "#/$defs/evaluation"}
Expand Down Expand Up @@ -68,7 +100,24 @@
"card_ids": {"$ref": "#/$defs/opaque_list"},
"revision_ids": {"$ref": "#/$defs/opaque_list"},
"evidence_ids": {"$ref": "#/$defs/opaque_list"},
"parent_digests": {"$ref": "#/$defs/digest_list"}
"parent_digests": {"$ref": "#/$defs/digest_list"},
"campaign_run_id": {"type": "string", "minLength": 1, "maxLength": 96},
"campaign_receipt_digest": {"$ref": "#/$defs/digest"},
"design_packet_artifact_digest": {"$ref": "#/$defs/digest"},
"retrieval_artifact_digest": {"$ref": "#/$defs/digest"},
"candidate_evaluation_artifact_digest": {"$ref": "#/$defs/digest"}
},
"dependentRequired": {
"campaign_run_id": [
"campaign_receipt_digest",
"design_packet_artifact_digest",
"retrieval_artifact_digest",
"candidate_evaluation_artifact_digest"
],
"campaign_receipt_digest": ["campaign_run_id"],
"design_packet_artifact_digest": ["campaign_run_id"],
"retrieval_artifact_digest": ["campaign_run_id"],
"candidate_evaluation_artifact_digest": ["campaign_run_id"]
}
},
"target": {
Expand Down Expand Up @@ -138,7 +187,11 @@
"edit": {
"type": "object",
"additionalProperties": false,
"required": ["path", "role", "operation", "before_digest", "after_digest", "content"],
"required": ["path", "role", "operation", "before_digest", "after_digest"],
"oneOf": [
{"required": ["content"], "not": {"required": ["content_file"]}},
{"required": ["content_file"], "not": {"required": ["content"]}}
],
"properties": {
"path": {"$ref": "#/$defs/repo_path"},
"role": {"enum": ["skill", "reference", "registry", "test", "documentation"]},
Expand All @@ -150,7 +203,11 @@
]
},
"after_digest": {"$ref": "#/$defs/digest"},
"content": {"type": "string", "minLength": 1, "maxLength": 65536}
"content": {"type": "string", "minLength": 1},
"content_file": {
"type": "string",
"pattern": "^candidate-content/[a-f0-9]{64}\\.utf8$"
}
}
},
"evaluation": {
Expand Down
37 changes: 35 additions & 2 deletions scripts/evaluate-design-intelligence-candidate.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,24 @@ def _validate_packet(packet: Mapping[str, Any]) -> tuple[str, dict[str, Any]]:
raise DesignEvaluationError("candidate packet rationale shape is unsupported")
if packet["target"].get("provider") != "stack" or packet["target"].get("package") != "stack" or packet["target"].get("upstream_pin") is not None:
raise DesignEvaluationError("candidate packet target is not Stack-owned")
if not isinstance(packet["edits"], list) or not 1 <= len(packet["edits"]) <= 5:
automatic_weekly = campaign_fields <= set(lineage)
if not isinstance(packet["edits"], list) or not packet["edits"]:
raise DesignEvaluationError("candidate packet edits are unsupported")
if not automatic_weekly and len(packet["edits"]) > 5:
raise DesignEvaluationError("manual candidate packet exceeds the file limit")
manual_total = 0
for edit in packet["edits"]:
if not isinstance(edit, Mapping) or set(edit) != {"path", "role", "operation", "before_digest", "after_digest", "content"}:
common = {"path", "role", "operation", "before_digest", "after_digest"}
expected_edit = common | ({"content_file"} if automatic_weekly else {"content"})
if not isinstance(edit, Mapping) or set(edit) != expected_edit:
raise DesignEvaluationError("candidate packet edit shape is unsupported")
if not automatic_weekly:
content = edit.get("content")
if not isinstance(content, str) or not content or len(content) > 65536:
raise DesignEvaluationError("manual candidate packet content is unsupported")
manual_total += len(content.encode("utf-8"))
if manual_total > 131072:
raise DesignEvaluationError("manual candidate packet exceeds the byte limit")
evaluation = packet.get("evaluation")
if not isinstance(evaluation, Mapping) or evaluation.get("profile") != "design-learning-v1" or evaluation.get("harness_required") is not True:
raise DesignEvaluationError("candidate packet is not bound to design-learning-v1")
Expand All @@ -176,6 +189,17 @@ def _validate_materialization(receipt: Mapping[str, Any], packet: Mapping[str, A
"authorization", "active_checkout", "isolation", "quarantine",
"activation", "next_gate",
}
lineage = packet.get("source_lineage")
campaign_fields = {
"campaign_run_id",
"campaign_receipt_digest",
"design_packet_artifact_digest",
"retrieval_artifact_digest",
"candidate_evaluation_artifact_digest",
}
automatic_weekly = isinstance(lineage, Mapping) and campaign_fields <= set(lineage)
if automatic_weekly:
expected.add("campaign_evidence")
if set(receipt) != expected or receipt.get("schema_version") != 1 or receipt.get("status") != "prepared" or receipt.get("receipt_kind") != "capability-change-materialization":
raise DesignEvaluationError("materialization receipt is incomplete or not prepared")
bound = receipt.get("change_digest", receipt.get("candidate_packet_digest"))
Expand Down Expand Up @@ -203,6 +227,15 @@ def _validate_materialization(receipt: Mapping[str, Any], packet: Mapping[str, A
activation = receipt.get("activation")
if not isinstance(activation, Mapping) or any(activation.get(key) is not False for key in ("active_pointer", "install", "publish", "draft_pr", "network_action")):
raise DesignEvaluationError("materialization receipt authorizes activation")
if automatic_weekly:
campaign_evidence = receipt.get("campaign_evidence")
if (
not isinstance(campaign_evidence, Mapping)
or set(campaign_evidence) != {"receipt_digest", "materiality_verified_before_materialization"}
or campaign_evidence.get("receipt_digest") != lineage.get("campaign_receipt_digest")
or campaign_evidence.get("materiality_verified_before_materialization") is not True
):
raise DesignEvaluationError("automatic materialization receipt lacks campaign evidence")


def _manifest(value: Any, expected_split: str, expected_digest: str) -> tuple[dict[str, Any], str]:
Expand Down
Loading