@event4u/agent-config 3.0.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent-src/commands/install-via-agent.md +129 -0
- package/.agent-src/commands/video/from-script.md +1 -1
- package/.agent-src/commands/video.md +1 -1
- package/.agent-src/contexts/execution/cheap-question-mechanics.md +81 -0
- package/.agent-src/rules/caveman-speak.md +2 -2
- package/.agent-src/rules/context-hygiene.md +36 -0
- package/.agent-src/rules/engineering-safety-floor.md +102 -0
- package/.agent-src/rules/finance-safety-floor.md +114 -0
- package/.agent-src/rules/git-history-discipline.md +1 -1
- package/.agent-src/rules/no-cheap-questions.md +34 -32
- package/.agent-src/rules/provider-lifecycle-discipline.md +4 -4
- package/.agent-src/rules/strategy-safety-floor.md +114 -0
- package/.agent-src/skills/agents-md-thin-root/SKILL.md +15 -9
- package/.agent-src/skills/async-python-patterns/SKILL.md +1 -1
- package/.agent-src/skills/project-analysis-node-express/SKILL.md +1 -1
- package/.agent-src/skills/readme-reviewer/SKILL.md +52 -3
- package/.agent-src/skills/readme-writing/SKILL.md +52 -4
- package/.agent-src/skills/readme-writing-package/SKILL.md +48 -5
- package/.agent-src/skills/systematic-debugging/SKILL.md +41 -0
- package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/.agent-src/templates/hooks/pre-commit-frontmatter +66 -0
- package/.agent-src/templates/hooks/pre-commit-roadmap-progress +78 -39
- package/.agent-src/templates/scripts/work_engine/_lib/agent_settings.py +4 -1
- package/.agent-src/templates/scripts/work_engine/orchestration.py +25 -11
- package/.claude-plugin/marketplace.json +2 -1
- package/AGENTS.md +10 -8
- package/CHANGELOG.md +233 -123
- package/README.md +165 -553
- package/config/agent-settings.template.yml +0 -7
- package/config/discovery/packs.yml +20 -0
- package/config/discovery/unassigned-artefacts.yml +2 -0
- package/config/gitignore-block.txt +19 -3
- package/dist/cli/commands/uiServe.js +13 -4
- package/dist/cli/commands/uiServe.js.map +1 -1
- package/dist/cli/registry.js +2 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/discovery/deprecation-report.md +7 -0
- package/dist/discovery/discovery-manifest.json +2107 -1409
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +9 -9
- package/dist/discovery/orphan-report.md +10 -0
- package/dist/discovery/packs.json +1002 -0
- package/dist/discovery/trust-report.md +26 -0
- package/dist/discovery/workspaces.json +705 -0
- package/dist/mcp/registry-manifest.json +4 -4
- package/dist/router.json +1623 -0
- package/dist/server/app.js +11 -3
- package/dist/server/app.js.map +1 -1
- package/dist/server/io/atomicMultiWrite.js +3 -1
- package/dist/server/io/atomicMultiWrite.js.map +1 -1
- package/dist/server/io/yamlIO.js +22 -0
- package/dist/server/io/yamlIO.js.map +1 -1
- package/dist/server/routes/ping.js +8 -0
- package/dist/server/routes/ping.js.map +1 -1
- package/dist/server/routes/schema.js +2 -2
- package/dist/server/routes/schema.js.map +1 -1
- package/dist/server/routes/settings.js +104 -23
- package/dist/server/routes/settings.js.map +1 -1
- package/dist/server/routes/userMd.js +37 -27
- package/dist/server/routes/userMd.js.map +1 -1
- package/dist/server/routes/wizard.js +256 -20
- package/dist/server/routes/wizard.js.map +1 -1
- package/dist/server/schemas/settings.js +0 -1
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/server/token.js +10 -3
- package/dist/server/token.js.map +1 -1
- package/dist/server/writeRoot.js +28 -11
- package/dist/server/writeRoot.js.map +1 -1
- package/dist/server/writeRoot.test.js +22 -4
- package/dist/server/writeRoot.test.js.map +1 -1
- package/dist/shared/userMd/formAdapter.js +29 -51
- package/dist/shared/userMd/formAdapter.js.map +1 -1
- package/dist/shared/userMd/schema.js +32 -104
- package/dist/shared/userMd/schema.js.map +1 -1
- package/dist/shared/userMd/utils.js +64 -50
- package/dist/shared/userMd/utils.js.map +1 -1
- package/dist/ui/assets/index-D-DY1ywI.js +35 -0
- package/dist/ui/assets/index-D-DY1ywI.js.map +1 -0
- package/dist/ui/index.html +1 -1
- package/docs/adrs/router/0001-three-tier-routing.md +5 -5
- package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +1 -1
- package/docs/architecture.md +3 -3
- package/docs/archive/CHANGELOG-pre-3.1.0.md +167 -0
- package/docs/catalog.md +30 -26
- package/docs/contracts/CHANGELOG-conventions.md +1 -1
- package/docs/contracts/agent-user-schema.md +6 -9
- package/docs/contracts/consumer-bridge.md +79 -0
- package/docs/contracts/discovery-manifest.md +209 -0
- package/docs/contracts/discovery-manifest.schema.json +77 -4
- package/docs/contracts/explain-trace.schema.json +1 -1
- package/docs/contracts/file-ownership-matrix.json +197 -13
- package/docs/contracts/frontmatter-contract.md +140 -0
- package/docs/contracts/gui-wizard.md +223 -0
- package/docs/contracts/installer-agent-mode.md +137 -0
- package/docs/contracts/kernel-membership.md +1 -1
- package/docs/contracts/mcp-tool-inventory.md +9 -9
- package/docs/contracts/namespace.md +6 -6
- package/docs/contracts/provider-lifecycle.md +5 -5
- package/docs/contracts/rule-router.md +4 -4
- package/docs/contracts/settings-api.md +53 -6
- package/docs/contracts/smoke-contracts.md +3 -3
- package/docs/contracts/trust-and-safety.md +144 -0
- package/docs/customization.md +2 -2
- package/docs/decisions/ADR-007-agent-discovery-scopes.md +12 -0
- package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +24 -0
- package/docs/decisions/ADR-015-discovery-manifest-contract.md +146 -0
- package/docs/decisions/ADR-016-installer-architecture.md +189 -0
- package/docs/decisions/ADR-017-monorepo-physical-layout.md +261 -0
- package/docs/decisions/ADR-018-trust-and-safety-layer.md +159 -0
- package/docs/decisions/ADR-019-router-json-dist-location.md +124 -0
- package/docs/decisions/ADR-020-global-only-consumer-scope.md +123 -0
- package/docs/decisions/ADR-021-deployment-shape.md +153 -0
- package/docs/decisions/INDEX.md +7 -0
- package/docs/deploy/connector-setup.md +129 -0
- package/docs/deploy/env-vars.md +70 -0
- package/docs/deploy/policy-cookbook.md +130 -0
- package/docs/deploy/quickstart.md +112 -0
- package/docs/distribution/public-install-smoke.md +68 -0
- package/docs/distribution/registries.md +55 -0
- package/docs/distribution/telemetry-privacy.md +128 -0
- package/docs/distribution/telemetry-schema.md +174 -0
- package/docs/featured-skills.md +95 -0
- package/docs/getting-started-by-role.md +19 -1
- package/docs/getting-started.md +2 -2
- package/docs/guidelines/agent-infra/installed-tools-manifest.md +11 -8
- package/docs/guidelines/docs/readme-size-and-splitting.md +53 -1
- package/docs/installation.md +27 -14
- package/docs/maintainers/dev-mode.md +105 -0
- package/docs/setup/per-ide/claude-desktop.md +3 -2
- package/docs/wizard.md +39 -4
- package/package.json +18 -1
- package/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
- package/scripts/_cli/cmd_doctor.py +150 -2
- package/scripts/_cli/cmd_explain.py +2 -1
- package/scripts/_cli/cmd_migrate_to_global.py +415 -0
- package/scripts/_cli/cmd_settings_migrate.py +146 -0
- package/scripts/_cli/explain_last/route.py +2 -1
- package/scripts/_dispatch.bash +36 -3
- package/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
- package/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
- package/scripts/_lib/agent_settings.py +4 -1
- package/scripts/_lib/agent_src.py +157 -0
- package/scripts/agent-config +17 -6
- package/scripts/audit_skill_descriptions.py +18 -6
- package/scripts/build_discovery_manifest.py +373 -17
- package/scripts/check_artefact_checksums.py +104 -0
- package/scripts/check_cluster_patterns.py +20 -4
- package/scripts/check_command_count_messaging.py +33 -14
- package/scripts/check_council_references.py +43 -4
- package/scripts/check_overlay_cascade_subdirs.py +7 -3
- package/scripts/check_references.py +5 -2
- package/scripts/check_reply_consistency.py +32 -9
- package/scripts/check_template_pin_drift.py +24 -7
- package/scripts/check_token_optimizer_freshness.py +18 -3
- package/scripts/compile_router.py +34 -2
- package/scripts/compress.py +162 -44
- package/scripts/config/presets.py +19 -1
- package/scripts/config/profiles.py +16 -1
- package/scripts/discovery_stats.py +70 -0
- package/scripts/expected_perms.json +47 -0
- package/scripts/generate_index.py +78 -46
- package/scripts/generate_ownership_matrix.py +98 -43
- package/scripts/generate_pack_manifests.py +183 -0
- package/scripts/install +18 -1
- package/scripts/install.py +934 -59
- package/scripts/install.sh +27 -9
- package/scripts/lint_agents_layout.py +93 -13
- package/scripts/lint_agents_md.py +1 -1
- package/scripts/lint_archived_skills.py +32 -16
- package/scripts/lint_bench_corpus.py +14 -2
- package/scripts/lint_command_tiers.py +15 -2
- package/scripts/lint_featured_skills.py +139 -0
- package/scripts/lint_framework_leakage.py +33 -6
- package/scripts/lint_global_paths.py +147 -0
- package/scripts/lint_orchestration_dsl.py +6 -3
- package/scripts/lint_pack_boundaries.py +147 -0
- package/scripts/lint_pack_first_win.py +103 -0
- package/scripts/lint_readme_jargon.py +131 -0
- package/scripts/lint_readme_size.py +33 -0
- package/scripts/lint_rule_interactions.py +23 -5
- package/scripts/lint_rule_tiers.py +12 -3
- package/scripts/lint_trust_coherence.py +212 -0
- package/scripts/measure_rule_budget.py +22 -4
- package/scripts/move_artefact.py +143 -0
- package/scripts/new_skill.py +148 -0
- package/scripts/plan_physical_move.py +353 -0
- package/scripts/refine_ticket_detect.py +30 -7
- package/scripts/release.py +22 -2
- package/scripts/schemas/command.schema.json +4 -0
- package/scripts/skill_linter.py +248 -118
- package/scripts/skill_trigger_eval.py +28 -8
- package/scripts/smoke/kernel.sh +1 -1
- package/scripts/smoke/router.sh +24 -5
- package/scripts/smoke/skills.sh +15 -7
- package/scripts/smoke_quickstart.py +11 -2
- package/scripts/snapshot_agent_outputs.py +144 -0
- package/scripts/update_counts.py +45 -17
- package/scripts/validate_decision_engine.py +9 -1
- package/scripts/validate_discovery_manifest.py +94 -0
- package/scripts/validate_frontmatter.py +39 -20
- package/scripts/verify_physical_move.py +185 -0
- package/templates/agent-user.md +0 -1
- package/templates/agent-user.yml +21 -0
- package/templates/minimal/agents-overrides-readme.md +46 -0
- package/templates/minimal/overrides-gitkeep +2 -0
- package/dist/ui/assets/index-BTRcKDlB.js +0 -39
- package/dist/ui/assets/index-BTRcKDlB.js.map +0 -1
- package/templates/minimal/agents-gitkeep +0 -2
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
adr: 015
|
|
3
|
+
status: accepted
|
|
4
|
+
date: 2026-05-21
|
|
5
|
+
decision: discovery-manifest-contract
|
|
6
|
+
supersedes: —
|
|
7
|
+
superseded_by: —
|
|
8
|
+
phase: v2.x · monorepo-phase-2-virtual-packs-discovery Phase 1
|
|
9
|
+
type: prospective
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# ADR-015 — Discovery Manifest Contract
|
|
13
|
+
|
|
14
|
+
## Status
|
|
15
|
+
|
|
16
|
+
**Accepted** · 2026-05-21 · in-session AI Council pass. Folds the Phase-2
|
|
17
|
+
intake invariant (`agents/tmp/refactor-package.txt`, last paragraph) and
|
|
18
|
+
the additive-vs-rewrite call into the schema. Phase-1 prerequisite for
|
|
19
|
+
[`monorepo-phase-2-virtual-packs-discovery`](../../agents/roadmaps/monorepo-phase-2-virtual-packs-discovery.md).
|
|
20
|
+
|
|
21
|
+
## Context
|
|
22
|
+
|
|
23
|
+
[ADR-013](ADR-013-discovery-frontmatter-contract.md) locked the five
|
|
24
|
+
per-artefact frontmatter keys. The release pipeline now needs a single
|
|
25
|
+
JSON contract — `dist/discovery/discovery-manifest.json` — that the
|
|
26
|
+
TypeScript installer (Phase 3), the browser wizard (Phase 6), the docs
|
|
27
|
+
site, and any third-party consumer read instead of walking the source
|
|
28
|
+
tree. The invariant from the founder intake:
|
|
29
|
+
|
|
30
|
+
> Beim Erstellen eines Releases müssen alle Skills, etc. nach Workspace
|
|
31
|
+
> und Pack untersucht werden, so dass das für den Installer gespeichert
|
|
32
|
+
> wird und zur Verfügung steht. Es soll keine manuelle Package &
|
|
33
|
+
> Workspace Liste gepflegt werden.
|
|
34
|
+
|
|
35
|
+
**No manual list. Ever.** The pack and workspace shape grows by stamping
|
|
36
|
+
frontmatter, not by editing a list.
|
|
37
|
+
|
|
38
|
+
A v1 manifest schema already lives at
|
|
39
|
+
[`docs/contracts/discovery-manifest.schema.json`](../contracts/discovery-manifest.schema.json)
|
|
40
|
+
(carried over from the archived R3 discovery roadmap). The Phase-2
|
|
41
|
+
roadmap §"Manifest shape" sketched an *ideal* shape that differs from
|
|
42
|
+
the on-disk schema in several places (per-artefact `checksum`,
|
|
43
|
+
optional `requires`, a `stats` block). The decision is whether to
|
|
44
|
+
rewrite the schema or extend it additively.
|
|
45
|
+
|
|
46
|
+
## Decision
|
|
47
|
+
|
|
48
|
+
**Extend the v1 schema additively.** Three changes, no removals, no
|
|
49
|
+
field renames, version stays `1`:
|
|
50
|
+
|
|
51
|
+
1. **`artefact.checksum`** — `sha256:<hex>`, REQUIRED. Computed over the
|
|
52
|
+
on-disk file bytes after frontmatter normalization (sorted keys,
|
|
53
|
+
trailing newline). Drift detector for the Phase-3 installer.
|
|
54
|
+
2. **`artefact.requires`** — `array<pack_id>`, OPTIONAL. Pack-level
|
|
55
|
+
dependency edges resolved by the installer; empty/absent means the
|
|
56
|
+
artefact has no extra pack requirements beyond its own `packs[]`.
|
|
57
|
+
3. **`stats`** — REQUIRED top-level object. `total_artefacts`,
|
|
58
|
+
`by_category`, `by_lifecycle`, `by_trust_level`. Cheap sanity surface
|
|
59
|
+
for `task discovery-stats` + downstream dashboards.
|
|
60
|
+
|
|
61
|
+
The Phase-2 roadmap's example also mentioned `id`, `owner`, and
|
|
62
|
+
`install.managed`. **Not adopted.** The path is the canonical artefact
|
|
63
|
+
identity (matches ADR-013), ownership is already encoded in
|
|
64
|
+
`workspaces[]` + `packs[]`, and `install.managed` adds a third
|
|
65
|
+
install-axis without a current consumer. Re-evaluate in Phase 5.
|
|
66
|
+
|
|
67
|
+
### Source-of-truth tree
|
|
68
|
+
|
|
69
|
+
The generator walks `.agent-src.uncompressed/`, **not** `.agent-src/`.
|
|
70
|
+
The Phase-2 roadmap text §Phase 2 says "the compressed canonical tree"
|
|
71
|
+
— that is a documentation slip. `augment-source-of-truth` rule states
|
|
72
|
+
that uncompressed is canonical; the compressed tree is a build output
|
|
73
|
+
and may be regenerated. Manifest pipelines that read build outputs are
|
|
74
|
+
fragile to bootstrap order.
|
|
75
|
+
|
|
76
|
+
### No git in the manifest
|
|
77
|
+
|
|
78
|
+
The roadmap example included `source_commit`. **Not adopted.** The
|
|
79
|
+
existing `scanner_version` (first 12 hex of `sha256(build_discovery_manifest.py)`)
|
|
80
|
+
already pins generator identity. Embedding `git rev-parse HEAD` breaks
|
|
81
|
+
hermetic determinism tests in environments without a git checkout
|
|
82
|
+
(CI shallow clones, vendor tarballs). A consumer that needs the commit
|
|
83
|
+
can pin from the surrounding release artefact (changelog, tag).
|
|
84
|
+
|
|
85
|
+
## Consequences
|
|
86
|
+
|
|
87
|
+
### Positive
|
|
88
|
+
|
|
89
|
+
- Existing consumers (the Phase-1 linter, the round-trip test, the
|
|
90
|
+
`lint_discovery_manifest.py` validator) keep working — top-level
|
|
91
|
+
`version` stays `1`, all v1 fields stay required.
|
|
92
|
+
- Per-artefact `checksum` makes the Phase-3 installer drift-detection
|
|
93
|
+
trivial — one hash compare per file.
|
|
94
|
+
- `requires` is opt-in: artefacts that don't need cross-pack deps cost
|
|
95
|
+
zero extra bytes.
|
|
96
|
+
- Stats are computed from the artefact list — no second walk of the
|
|
97
|
+
tree, no risk of stats/list desync.
|
|
98
|
+
|
|
99
|
+
### Negative
|
|
100
|
+
|
|
101
|
+
- Every artefact entry grows by ~80 bytes (the checksum). For ~420
|
|
102
|
+
artefacts, the manifest grows ~33 KB. Acceptable.
|
|
103
|
+
- The first build after this ADR rewrites every artefact entry; the
|
|
104
|
+
diff is large. Reviewed once and committed.
|
|
105
|
+
|
|
106
|
+
### Neutral
|
|
107
|
+
|
|
108
|
+
- `version` stays `1`. A future breaking change (rename `packs` to
|
|
109
|
+
`pack_ids`, drop `unassigned`, etc.) bumps to `2`. This ADR sets the
|
|
110
|
+
precedent that **additive** changes do not bump.
|
|
111
|
+
|
|
112
|
+
## Determinism contract
|
|
113
|
+
|
|
114
|
+
Two builds of the same source tree MUST produce byte-identical JSON
|
|
115
|
+
when `generated_at` is normalized. Specifically:
|
|
116
|
+
|
|
117
|
+
- All arrays sorted (`artefacts` by `path`, `workspaces`/`packs` in
|
|
118
|
+
vocabulary order, `requires`/`workspaces[]`/`packs[]` per-entry sorted).
|
|
119
|
+
- JSON serialized with `sort_keys=True`, `indent=2`, trailing newline.
|
|
120
|
+
- The global `checksum` covers the manifest minus `generated_at` and
|
|
121
|
+
itself (zeroed during hash input).
|
|
122
|
+
- Per-artefact `checksum` covers the file content with frontmatter
|
|
123
|
+
normalized (sorted keys, trailing newline, no trailing whitespace).
|
|
124
|
+
|
|
125
|
+
## Failure modes guarded against
|
|
126
|
+
|
|
127
|
+
- **Manual drift** — no pack list to hand-edit; new packs/workspaces
|
|
128
|
+
enter via frontmatter stamps on artefacts.
|
|
129
|
+
- **Stale manifest in release** — Phase 3 ships `task validate-discovery-manifest`
|
|
130
|
+
which re-builds to a tempdir and `diff`s against the committed file.
|
|
131
|
+
- **Checksum collision with content edits** — per-artefact `checksum`
|
|
132
|
+
surfaces any file mutation; the installer can refuse to overwrite a
|
|
133
|
+
user-modified artefact (Phase 3).
|
|
134
|
+
- **`version: 1` reused for breaking changes** — this ADR explicitly
|
|
135
|
+
scopes `version: 1` to additive evolutions; breaking → bump + new ADR.
|
|
136
|
+
|
|
137
|
+
## References
|
|
138
|
+
|
|
139
|
+
- [ADR-013](ADR-013-discovery-frontmatter-contract.md) — frontmatter
|
|
140
|
+
contract (the input side of this manifest).
|
|
141
|
+
- [`docs/contracts/discovery-manifest.schema.json`](../contracts/discovery-manifest.schema.json)
|
|
142
|
+
— the locked schema.
|
|
143
|
+
- [`docs/contracts/discovery-manifest.md`](../contracts/discovery-manifest.md)
|
|
144
|
+
— worked examples + consumer guide.
|
|
145
|
+
- [`agents/roadmaps/monorepo-phase-2-virtual-packs-discovery.md`](../../agents/roadmaps/monorepo-phase-2-virtual-packs-discovery.md)
|
|
146
|
+
— the implementing roadmap.
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
adr: 016
|
|
3
|
+
status: accepted
|
|
4
|
+
date: 2026-05-21
|
|
5
|
+
decision: installer-architecture
|
|
6
|
+
supersedes: —
|
|
7
|
+
superseded_by: —
|
|
8
|
+
phase: v2.x · monorepo-phase-3-typescript-installer
|
|
9
|
+
type: prospective
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# ADR-016 — TypeScript Installer Architecture
|
|
13
|
+
|
|
14
|
+
## Status
|
|
15
|
+
|
|
16
|
+
**Accepted** · 2026-05-21 · external AI Council pass (`claude-sonnet-4-5`
|
|
17
|
+
+ `gpt-4o`, 2 rounds, `design` lens, actual cost $0.13) on
|
|
18
|
+
[`agents/roadmaps/monorepo-phase-3-typescript-installer.md`](../../agents/roadmaps/monorepo-phase-3-typescript-installer.md).
|
|
19
|
+
Council issued **conditional approval** with five blockers; this ADR
|
|
20
|
+
folds each blocker into the design before Phase 3.1 starts.
|
|
21
|
+
|
|
22
|
+
Session: [`agents/runtime/council/responses/phase-3-installer-design.json`](../../agents/runtime/council/responses/phase-3-installer-design.json) <!-- council-ref-allowed: ADR decision-trace -->
|
|
23
|
+
|
|
24
|
+
## Context
|
|
25
|
+
|
|
26
|
+
Phase 3 of the monorepo plan replaces the shell-based `install.sh` with
|
|
27
|
+
a TypeScript Core Installer that drives interactive TUI, non-interactive
|
|
28
|
+
CI flags, and a structured **agent-mode** JSON protocol over stdio. It
|
|
29
|
+
consumes [`dist/discovery/discovery-manifest.json`](../../dist/discovery/discovery-manifest.json)
|
|
30
|
+
(locked by [ADR-015](ADR-015-discovery-manifest-contract.md)) and
|
|
31
|
+
writes managed files into the consumer's `.augment/` and `.agent-src/`,
|
|
32
|
+
tracked in `agents/agent-config.lock.yml`.
|
|
33
|
+
|
|
34
|
+
The council raised five architectural risks that, left unaddressed,
|
|
35
|
+
would force post-merge rework in Phase 5 (trust) and Phase 6 (browser
|
|
36
|
+
wizard). This ADR locks the resolution of each.
|
|
37
|
+
|
|
38
|
+
## Decision
|
|
39
|
+
|
|
40
|
+
### 1. Lockfile schema v1 records provenance, not just paths
|
|
41
|
+
|
|
42
|
+
```yaml
|
|
43
|
+
schema_version: 1
|
|
44
|
+
agent_config_version: 2.0.0
|
|
45
|
+
manifest_sha256: <hex> # sha256 of the consumed discovery-manifest.json
|
|
46
|
+
generated_at: 2026-05-21T12:00:00Z
|
|
47
|
+
workspaces: [engineering, governance]
|
|
48
|
+
packs:
|
|
49
|
+
- id: pack.laravel
|
|
50
|
+
version: 2.0.0
|
|
51
|
+
auto_selected: false
|
|
52
|
+
required_by: []
|
|
53
|
+
files:
|
|
54
|
+
- path: .augment/skills/laravel/SKILL.md
|
|
55
|
+
pack: pack.laravel
|
|
56
|
+
pack_version: 2.0.0
|
|
57
|
+
sha256: <hex>
|
|
58
|
+
manifest_sha256: <hex> # which manifest sourced this file
|
|
59
|
+
managed: true
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`manifest_sha256` is per-file (not just per-lockfile) so Phase 5 trust
|
|
63
|
+
gates can answer "which manifest claimed this artefact was safe?"
|
|
64
|
+
without needing a lockfile rewrite.
|
|
65
|
+
|
|
66
|
+
### 2. Overrides live in a separate file the installer never writes
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
# agents/agent-config.overrides.yml — user-managed, installer reads but never writes
|
|
70
|
+
schema_version: 1
|
|
71
|
+
overrides:
|
|
72
|
+
- path: agents/overrides/skills/laravel/SKILL.md
|
|
73
|
+
shadows: .augment/skills/laravel/SKILL.md
|
|
74
|
+
reason: "Custom prompt for our team's Laravel style"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The lockfile (`.lock.yml`) is **append-only by the installer**;
|
|
78
|
+
overrides (`.overrides.yml`) are **read-only to the installer**.
|
|
79
|
+
`validate` cross-references the two. This resolves the source-of-truth
|
|
80
|
+
ambiguity the council flagged on `managed: false`.
|
|
81
|
+
|
|
82
|
+
### 3. Merge decision table replaces "three-way merge" handwaving
|
|
83
|
+
|
|
84
|
+
| Disk | Lock | Upstream | Override? | Action |
|
|
85
|
+
|---------|------|----------|-----------|--------------------------------------|
|
|
86
|
+
| A | A | A | — | no-op |
|
|
87
|
+
| A | A | B | no | write B, update lock |
|
|
88
|
+
| A | A | B | yes | write B to `.augment/`, leave override |
|
|
89
|
+
| A | A | absent | — | offer prune |
|
|
90
|
+
| X (drift) | A | A | — | warn, suggest `validate --fix` |
|
|
91
|
+
| X (drift) | A | B | no | error: manual merge required |
|
|
92
|
+
| X (drift) | A | B | yes | error: override may be stale |
|
|
93
|
+
| absent | A | B | — | write B (recreate) |
|
|
94
|
+
|
|
95
|
+
Encoded in `src/sync/merge-strategy.ts`; covered by
|
|
96
|
+
`tests/sync-algorithm.test.ts` with one case per row.
|
|
97
|
+
|
|
98
|
+
### 4. Agent mode: strict question-ID validation (stateless)
|
|
99
|
+
|
|
100
|
+
Of the three options the council surfaced (session token, nonce,
|
|
101
|
+
strict sequencing) we adopt **strict sequencing**: the CLI tracks the
|
|
102
|
+
current question id in the manifest of expected answers; any
|
|
103
|
+
`--answer` that does not match the current question id returns:
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{ "status": "error", "protocol_version": 1, "reason": "out_of_order",
|
|
107
|
+
"expected_question_id": "q1.workspaces", "received": "q2.packs" }
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Stateless (no session file), enforceable, and easy to test. Nonces
|
|
111
|
+
can be added later under the same protocol version if the threat model
|
|
112
|
+
hardens.
|
|
113
|
+
|
|
114
|
+
### 5. Atomic writes via staging directory
|
|
115
|
+
|
|
116
|
+
Every command that writes to `.augment/`, `.agent-src/`, or the
|
|
117
|
+
lockfile stages changes under `.augment/.agent-config-staging/<uuid>/`,
|
|
118
|
+
verifies sha256s against intended manifest entries, then performs:
|
|
119
|
+
|
|
120
|
+
1. Atomic rename: `staging/.augment/foo.md` → `.augment/foo.md`
|
|
121
|
+
(per-file `fs.renameSync` is atomic on POSIX and Windows ≥ 10).
|
|
122
|
+
2. Lockfile written last (so a mid-flight crash leaves the lockfile
|
|
123
|
+
pointing at the previous-good state, not the partial new state).
|
|
124
|
+
3. Staging directory removed on success.
|
|
125
|
+
|
|
126
|
+
`init`, `sync`, and `prune` share the same `commitAtomic(staging)`
|
|
127
|
+
helper.
|
|
128
|
+
|
|
129
|
+
### 6. `protocol_version` field on every agent-mode response
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{ "status": "question", "protocol_version": 1, "id": "q1.workspaces", ... }
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Pinned at 1 for Phase 3; bumped to 2 only on breaking change.
|
|
136
|
+
Versioning the schema (not just `next_call`) lets Phase 5 add trust
|
|
137
|
+
banners without breaking existing agents.
|
|
138
|
+
|
|
139
|
+
## Consequences
|
|
140
|
+
|
|
141
|
+
**Positive**
|
|
142
|
+
|
|
143
|
+
- Phase 5 (trust) can add `trust_level` to lockfile packs without a
|
|
144
|
+
schema migration (already at `schema_version: 1`; trust fields
|
|
145
|
+
become optional v1 additions).
|
|
146
|
+
- Phase 6 (browser wizard) reuses the same agent-mode JSON shape over
|
|
147
|
+
a local HTTP server; the strict-sequencing model maps to HTTP
|
|
148
|
+
request/response naturally.
|
|
149
|
+
- `agents/agent-config.overrides.yml` becomes a Git-tracked
|
|
150
|
+
declaration of user intent — diffable, reviewable, and never
|
|
151
|
+
silently overwritten.
|
|
152
|
+
- Atomic writes give `sync` and `prune` crash safety without a
|
|
153
|
+
rollback subcommand.
|
|
154
|
+
|
|
155
|
+
**Negative**
|
|
156
|
+
|
|
157
|
+
- One extra YAML file in the consumer repo (overrides).
|
|
158
|
+
- Strict sequencing means agents must replay the conversation if they
|
|
159
|
+
lose state mid-call; this is the simplest threat-model resolution
|
|
160
|
+
but pushes complexity onto agent authors.
|
|
161
|
+
- Per-file `manifest_sha256` adds ~64 bytes per lockfile entry; for a
|
|
162
|
+
500-file install that's 32 KB. Acceptable.
|
|
163
|
+
|
|
164
|
+
**Deferred to Phase 5**
|
|
165
|
+
|
|
166
|
+
- npm package signature verification (SLSA Level 3 / `npm
|
|
167
|
+
provenance`). Reviewer A's "sign the package, not just the
|
|
168
|
+
manifest" call. Phase 5 owns trust gates; Phase 3 only records
|
|
169
|
+
provenance.
|
|
170
|
+
|
|
171
|
+
## Rejected alternatives
|
|
172
|
+
|
|
173
|
+
- **Single lockfile with `overrides:` section** — the original spec.
|
|
174
|
+
Rejected because the installer cannot detect untracked
|
|
175
|
+
user-authored overrides without either scanning `agents/overrides/`
|
|
176
|
+
(which a malicious agent could pollute) or trusting user edits to
|
|
177
|
+
the lockfile (which breaks "lockfile is installer-generated").
|
|
178
|
+
- **Nonce-based agent mode** — overkill for v1. Re-evaluate when
|
|
179
|
+
agent mode lands on a remote surface.
|
|
180
|
+
- **Rollback subcommand with lockfile history** — atomic writes
|
|
181
|
+
already give us crash safety; full version history is a Phase 6
|
|
182
|
+
concern (the browser wizard wants a timeline).
|
|
183
|
+
|
|
184
|
+
## References
|
|
185
|
+
|
|
186
|
+
- Roadmap: [`agents/roadmaps/monorepo-phase-3-typescript-installer.md`](../../agents/roadmaps/monorepo-phase-3-typescript-installer.md)
|
|
187
|
+
- Discovery manifest: [ADR-015](ADR-015-discovery-manifest-contract.md)
|
|
188
|
+
- CLI shell precedent: [ADR-012](ADR-012-typescript-cli-shell.md)
|
|
189
|
+
- Council session: [`agents/runtime/council/responses/phase-3-installer-design.json`](../../agents/runtime/council/responses/phase-3-installer-design.json) <!-- council-ref-allowed: ADR decision-trace -->
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
---
|
|
2
|
+
adr: 017
|
|
3
|
+
status: accepted
|
|
4
|
+
date: 2026-05-21
|
|
5
|
+
decision: monorepo-physical-layout
|
|
6
|
+
supersedes: —
|
|
7
|
+
superseded_by: —
|
|
8
|
+
phase: v2.x · monorepo-phase-4-physical-package-layout
|
|
9
|
+
type: prospective
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# ADR-017 — Monorepo Physical Package Layout
|
|
13
|
+
|
|
14
|
+
## Status
|
|
15
|
+
|
|
16
|
+
**Accepted** · 2026-05-21 · external AI Council pass (`claude-sonnet-4-5`
|
|
17
|
+
+ `gpt-4o`, 2 rounds, `design` lens, actual cost $0.0961) on the Phase 4
|
|
18
|
+
roadmap. Council issued **conditional approval** with four blockers and
|
|
19
|
+
two refinements; this revision folds each into the design before the
|
|
20
|
+
`--apply` step runs.
|
|
21
|
+
|
|
22
|
+
Session: [`agents/runtime/council/responses/phase-4-physical-layout.json`](../../agents/runtime/council/responses/phase-4-physical-layout.json) <!-- council-ref-allowed: ADR decision-trace -->
|
|
23
|
+
|
|
24
|
+
Companion artefacts:
|
|
25
|
+
- [`agents/roadmaps/monorepo-phase-4-physical-package-layout.md`](../../agents/roadmaps/monorepo-phase-4-physical-package-layout.md)
|
|
26
|
+
- [`dist/migration/move-plan.json`](../../dist/migration/move-plan.json) (94 moves, 432 core, 0 conflicts)
|
|
27
|
+
- [`dist/migration/pre-move-snapshot.json`](../../dist/migration/pre-move-snapshot.json) (744 files hashed)
|
|
28
|
+
- [`scripts/plan_physical_move.py`](../../scripts/plan_physical_move.py) (plan + apply)
|
|
29
|
+
- [`scripts/verify_physical_move.py`](../../scripts/verify_physical_move.py) (post-move diff vs. snapshot)
|
|
30
|
+
|
|
31
|
+
## Context
|
|
32
|
+
|
|
33
|
+
Phases 1–3 produced the artefact metadata (`packs[]`, `workspaces[]`,
|
|
34
|
+
`trust.level`, `install.removable`), the discovery manifest, and the
|
|
35
|
+
TypeScript installer **without** moving a single file. The on-disk
|
|
36
|
+
source tree is still flat:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
.agent-src.uncompressed/
|
|
40
|
+
rules/ # 72 entries
|
|
41
|
+
skills/ # 218 entries
|
|
42
|
+
commands/ # 129 entries
|
|
43
|
+
personas/ # 24 entries
|
|
44
|
+
contexts/ # 32 entries
|
|
45
|
+
templates/ # 24 scaffolds
|
|
46
|
+
…
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
This means the metadata says "this skill belongs to `pack.laravel`" but
|
|
50
|
+
the file lives next to a Symfony skill and a finance persona. Consumers
|
|
51
|
+
of the npm release, the consumer-side `.augment/` overlay, and the
|
|
52
|
+
upcoming Phase 5 trust gates would all benefit from physical separation
|
|
53
|
+
that mirrors the manifest. Phase 4 introduces that separation in one PR
|
|
54
|
+
with a deterministic, history-preserving migration.
|
|
55
|
+
|
|
56
|
+
The four risks the council flagged on Phase 3 (history loss, stale path
|
|
57
|
+
refs, cross-pack drift, hand-edited paths) all bite hardest here.
|
|
58
|
+
|
|
59
|
+
## Decision
|
|
60
|
+
|
|
61
|
+
### 1. Layout — one core, one folder per pack
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
packages/
|
|
65
|
+
core/
|
|
66
|
+
installer/ # TS CLI (already there post-Phase 3)
|
|
67
|
+
.agent-src.uncompressed/ # rules + kernel skills + scaffolds
|
|
68
|
+
pack-php/.agent-src.uncompressed/
|
|
69
|
+
pack-laravel/.agent-src.uncompressed/
|
|
70
|
+
…
|
|
71
|
+
pack-ai-video/.agent-src.uncompressed/
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
No flag day: every commit between "before" and "after" the move builds
|
|
75
|
+
and ships. The TS installer needs zero behavioural changes — only the
|
|
76
|
+
`manifest-loader.ts` path roots flip.
|
|
77
|
+
|
|
78
|
+
### 2. Mapping rules (deterministic, lockfile-stable)
|
|
79
|
+
|
|
80
|
+
Implemented in [`scripts/plan_physical_move.py`](../../scripts/plan_physical_move.py):
|
|
81
|
+
|
|
82
|
+
1. **Kernel rules** → `packages/core/` (allowlist, sanity-checked against
|
|
83
|
+
[`docs/contracts/kernel-membership.md`](../contracts/kernel-membership.md) §4).
|
|
84
|
+
The locked set is 10 entries; `user-interrupt-priority` was admitted
|
|
85
|
+
post-P2.2 and is included.
|
|
86
|
+
2. **Core-trust artefacts** (`trust.level: core` AND
|
|
87
|
+
`install.removable: false`) → `packages/core/`.
|
|
88
|
+
3. **Non-frontmatter trees** (`templates/`, `profiles/`, `presets/`,
|
|
89
|
+
`contexts/`, `user-types/`, `scripts/`, `ghostwriter/`, `packs/`,
|
|
90
|
+
`personas/`) → `packages/core/` verbatim. These are scaffolding and
|
|
91
|
+
product internals, not pack-routable artefacts.
|
|
92
|
+
4. **Skill auxiliary files** (`prompts/*.md`, sub-pages inside a skill
|
|
93
|
+
directory) → inherit the destination of the nearest `SKILL.md` in
|
|
94
|
+
the parent directory tree. Codified to fix 9 false-positive conflicts
|
|
95
|
+
on Phase 4 dry-run.
|
|
96
|
+
5. **Pack-routable artefacts** → `packages/pack-<id>/`, where `<id>` is
|
|
97
|
+
the first entry in `packs[]`. Tie-breaking by alphabetic pack id.
|
|
98
|
+
6. **Quarantined scaffolds** (the 26 entries in
|
|
99
|
+
[`config/discovery/unassigned-artefacts.yml`](../../config/discovery/unassigned-artefacts.yml))
|
|
100
|
+
→ `packages/core/` with `unassigned scaffold:` reason recorded in the
|
|
101
|
+
move plan. The top-level `.agent-src.uncompressed/README.md` was added
|
|
102
|
+
here during dry-run.
|
|
103
|
+
7. **`primary pack: meta`** → `packages/core/` (package-internal
|
|
104
|
+
scaffolding, not a real pack).
|
|
105
|
+
8. **Unknown / missing pack** → fall back to `packages/core/` AND emit
|
|
106
|
+
a conflict. `--apply` refuses to run if `conflicts > 0`.
|
|
107
|
+
|
|
108
|
+
### 3. Mechanic — `git mv` only
|
|
109
|
+
|
|
110
|
+
Every move uses `git mv` so `git log --follow` keeps working on every
|
|
111
|
+
artefact post-move. The plan script's `--apply` mode is the only entry
|
|
112
|
+
point; it refuses if any conflict remains. No human-edited paths.
|
|
113
|
+
|
|
114
|
+
### 4. Byte-identity contract
|
|
115
|
+
|
|
116
|
+
`task sync` + `task build-discovery` after the move must produce
|
|
117
|
+
`.agent-src/`, `.augment/`, and `dist/discovery/discovery-manifest.json`
|
|
118
|
+
byte-identical to the pre-move snapshot **except** for
|
|
119
|
+
`artefacts[].path` values. [`scripts/verify_physical_move.py`](../../scripts/verify_physical_move.py)
|
|
120
|
+
captures a post-move snapshot and diffs against
|
|
121
|
+
`dist/migration/pre-move-snapshot.json`; the only allowed delta is the
|
|
122
|
+
`path` field per artefact.
|
|
123
|
+
|
|
124
|
+
### 5. Rollback
|
|
125
|
+
|
|
126
|
+
The whole move is a single PR. `git revert <merge-sha>` restores the
|
|
127
|
+
prior layout in one commit; the next `task sync` round-trip is back to
|
|
128
|
+
the pre-move snapshot. No data migration, no manifest schema change, no
|
|
129
|
+
installer behaviour change.
|
|
130
|
+
|
|
131
|
+
## Consequences
|
|
132
|
+
|
|
133
|
+
### Positive
|
|
134
|
+
|
|
135
|
+
- Metadata-to-disk parity: a consumer can now `cd packages/pack-laravel`
|
|
136
|
+
and see exactly what `pack.laravel` ships, no manifest indirection.
|
|
137
|
+
- Phase 5 (trust) lands cleanly inside `packages/core/installer/` and
|
|
138
|
+
reads per-pack metadata from `packages/pack-*/.agent-src.uncompressed/`.
|
|
139
|
+
- Phase 6 (browser wizard) maps packs 1:1 to its left-nav.
|
|
140
|
+
- Cross-pack drift is now lintable (`task lint-pack-boundaries` in
|
|
141
|
+
Phase 4.4 of the roadmap).
|
|
142
|
+
- `git log --follow` keeps working — no history loss.
|
|
143
|
+
|
|
144
|
+
### Negative
|
|
145
|
+
|
|
146
|
+
- One large PR (~526 file moves). Reviewers need the move plan as the
|
|
147
|
+
primary review artefact, not per-file diff inspection.
|
|
148
|
+
- Editors with the old tree open will hit broken paths until they pull.
|
|
149
|
+
Mitigated by docs-update in the same PR (`AGENTS.md`, `README.md`,
|
|
150
|
+
`docs/architecture.md`).
|
|
151
|
+
- Path refs in CI workflows, Taskfile, and the discovery scanner need
|
|
152
|
+
one-line updates. The roadmap enumerates each.
|
|
153
|
+
|
|
154
|
+
### Neutral
|
|
155
|
+
|
|
156
|
+
- The npm tarball shape changes (paths only). The installer copies
|
|
157
|
+
files by manifest entry, not by source path, so consumers see no
|
|
158
|
+
difference.
|
|
159
|
+
|
|
160
|
+
## Alternatives considered
|
|
161
|
+
|
|
162
|
+
1. **Phased move (one pack per PR).** Rejected: 16 PRs, partial states
|
|
163
|
+
on disk for weeks, `task sync` invariants harder to enforce.
|
|
164
|
+
2. **Symlink farm.** Rejected: Windows support, npm tarball duplication,
|
|
165
|
+
and the installer would have to dereference paths.
|
|
166
|
+
3. **Stay flat, lift packs into manifest-only.** Rejected: this is the
|
|
167
|
+
current state; it forfeits the metadata-to-disk parity that Phase 5
|
|
168
|
+
and Phase 6 depend on.
|
|
169
|
+
|
|
170
|
+
## Council resolution (Round 2)
|
|
171
|
+
|
|
172
|
+
Four blocking items and two refinements raised by the council; each
|
|
173
|
+
resolved before `--apply` runs.
|
|
174
|
+
|
|
175
|
+
### B1 — Final source location of `.agent-src.uncompressed/`
|
|
176
|
+
|
|
177
|
+
The council asked whether the source tree nests inside `packages/core/`
|
|
178
|
+
(current design) or becomes a peer `pack-core/`. **Decision: keep
|
|
179
|
+
`packages/core/.agent-src.uncompressed/`.** Three reasons:
|
|
180
|
+
|
|
181
|
+
1. `packages/core/` is the engine + installer + kernel rules +
|
|
182
|
+
scaffolding (templates, profiles, presets, contexts, user-types).
|
|
183
|
+
None of that is pack-routable; making it a "pack" inverts the
|
|
184
|
+
product mental model.
|
|
185
|
+
2. The installer in `packages/core/installer/` already lives next to
|
|
186
|
+
the manifest loader; co-locating the rules that bootstrap the
|
|
187
|
+
installer reduces cross-package import chains.
|
|
188
|
+
3. The TS installer consumes `dist/discovery/discovery-manifest.json`,
|
|
189
|
+
not source paths, so the "location is privileged" critique does not
|
|
190
|
+
bite — the manifest is the API.
|
|
191
|
+
|
|
192
|
+
### B2 — `git mv` rename detection at scale
|
|
193
|
+
|
|
194
|
+
Default `diff.renameLimit` since git 2.9 is 1000. Plan: 94 explicit
|
|
195
|
+
`git mv` operations + 1 directory rename for `core/`. Each move is
|
|
196
|
+
content-identical (no edits during move). Test gate: after `--apply`,
|
|
197
|
+
run `git diff --name-status HEAD~1` and assert `R100` (100 % rename
|
|
198
|
+
similarity) on every moved file. Verification script enforces this.
|
|
199
|
+
|
|
200
|
+
### B3 — Consumer-facing output contract
|
|
201
|
+
|
|
202
|
+
`task sync` writes `.agent-src/` (compressed) and `.augment/` (overlay)
|
|
203
|
+
at repo root — **unchanged** location and structure. The byte-identity
|
|
204
|
+
contract covers exactly these two trees plus the discovery manifest.
|
|
205
|
+
What changes:
|
|
206
|
+
|
|
207
|
+
- `dist/discovery/discovery-manifest.json` `artefacts[].path` values
|
|
208
|
+
(path-only delta, enforced by `verify_physical_move.py`).
|
|
209
|
+
- npm tarball internal paths (consumers never touch these; installer
|
|
210
|
+
uses manifest entries).
|
|
211
|
+
|
|
212
|
+
What stays identical: `.agent-src/`, `.augment/`, manifest checksums
|
|
213
|
+
of non-path fields, lockfile schema, installer behaviour.
|
|
214
|
+
|
|
215
|
+
### B4 — Installer dual-layout support
|
|
216
|
+
|
|
217
|
+
Not required. Consumers install via `npm install
|
|
218
|
+
@event4u/agent-config@<version>`; each version ships a self-consistent
|
|
219
|
+
tarball. There is no "consumer pulls mid-PR" scenario because consumers
|
|
220
|
+
do not consume the source repo — they consume the published tarball.
|
|
221
|
+
Source-tree contributors who pull the merge commit move atomically
|
|
222
|
+
with the layout. The "dual-layout" complexity the council proposed
|
|
223
|
+
exists in code-host-as-CDN ecosystems we do not target.
|
|
224
|
+
|
|
225
|
+
### R1 — `primary_pack` frontmatter field
|
|
226
|
+
|
|
227
|
+
`scripts/plan_physical_move.py` already uses `packs[0]` as the
|
|
228
|
+
destination. Round-2 hardening: the plan also reads an explicit
|
|
229
|
+
`primary_pack:` frontmatter field when present and prefers it over
|
|
230
|
+
`packs[0]`. Lint that requires `primary_pack` on every pack-routable
|
|
231
|
+
artefact lands in Phase 4.4 (out of scope for the move itself; the
|
|
232
|
+
move uses today's data and the new fallback).
|
|
233
|
+
|
|
234
|
+
### R2 — Pre-move pack-boundary lint
|
|
235
|
+
|
|
236
|
+
The current plan dry-run finds 0 conflicts after the auxiliary-file
|
|
237
|
+
inheritance rule landed. A cross-pack-reference lint (an artefact in
|
|
238
|
+
`pack.laravel` citing one in `pack.symfony` without a declared
|
|
239
|
+
dependency) is deferred to Phase 4.4 — the move itself does not edit
|
|
240
|
+
file contents, so cross-pack references survive the move byte-identical.
|
|
241
|
+
|
|
242
|
+
## Compliance + verification
|
|
243
|
+
|
|
244
|
+
- `scripts/plan_physical_move.py` is the only mover. Hand-edited paths
|
|
245
|
+
fail `task verify-physical-move`.
|
|
246
|
+
- `scripts/verify_physical_move.py` enforces the byte-identity
|
|
247
|
+
contract.
|
|
248
|
+
- `task ci` runs both as a hard gate post-move.
|
|
249
|
+
- Per-pack lint matrix lands in Phase 4.4 of the roadmap.
|
|
250
|
+
|
|
251
|
+
## Future work
|
|
252
|
+
|
|
253
|
+
- Phase 4.4 — per-pack `pack.yaml` + boundary lint.
|
|
254
|
+
- Phase 4.5 — contributor scaffolders (`task new-skill`,
|
|
255
|
+
`task move-artefact`).
|
|
256
|
+
- Phase 6 (optional) — split distribution per pack as separate npm
|
|
257
|
+
packages. Specification removed 2026-05-24 (drift audit, finding
|
|
258
|
+
F-1): the 150-line "documented-only" addendum had zero consumers
|
|
259
|
+
and ~6 months of unmaintained drift versus the bundled-tarball
|
|
260
|
+
model. Restore from git history at `d06af2c5` if a real consumer
|
|
261
|
+
ever asks for a single-pack install path.
|