6.8 KiB
Reading Active-Space Rule Files
Audience: any agent that needs to read team-affirmed practices from
aidlc/spaces/<active-space>/memory/. Owner of this file: framework. Cited byaidlc-pipeline-deploy-agent/branching-strategies.mdand by other agents that adopt practices-aware behaviour.
The rules namespace resolves through a strict-additive five-layer chain
at workflow start: org → team → project → phase → stage. The first three
files are aidlc/spaces/<active-space>/memory/{org,team,project}.md;
phases/<phase>.md attaches because the stage's frontmatter phase: <name>
selects it. Stage rules are reserved for future use. The compile bakes the
resolved chain into each stage node's rules_in_context; every applicable
rule appears in the chain - nothing drops at runtime. At stage entry the
engine delivers each substantive rule file through an ordered sequence of
bounded load-steering directives before run-stage (empty templates are
dropped per § 1; there is no size-based path fallback). This file documents
how to read those layers safely when an agent needs a practice outside that
delivery sequence (tool shaping, question prompts).
1. Empty-template detection
A rule section is empty when every non-blank line in its body begins
with <!-- or is whitespace. The template ships with HTML-comment
placeholders illustrating affirmed-state examples; until the team has
affirmed practices, every section is empty by this rule.
When you read a section and find it empty, fall back to the next layer (see § 3). Do not parse the example prose — the comments exist for human readers, not for agent inference.
Example empty section:
## Way of Working
<!-- Populated by practices-discovery affirmation. Example after affirmation:
"We squash-merge to `main`. Trunk-based; feature branches resolve in 1-2 days." -->
Example populated section:
## Way of Working
We squash-merge to `main`. Trunk-based; feature branches resolve in 1-2 days.
The first body line being <!-- is the empty signal; the second body line
being prose is the populated signal.
2. Semantic-topic matching
Heading shapes can drift between team.md, org.md, project.md, and the
per-agent KB that consumes them. Match by topic, not by exact-string
heading.
For the way of working / branching / merge topic:
- Prefer an exact
## Way of Workingheading. - Fall back to any
##heading containingbranch,merge, orway(case-insensitive).
For the walking skeleton topic:
- Prefer
## Walking Skeleton. - Fall back to any heading containing
skeleton(case-insensitive).
For the testing topic:
- Prefer
## Testing Posture. - Fall back to any heading containing
test(case-insensitive). - For Code Generation, resolve the explicit
MethodologyandOrderingstatements independently from coverage, tooling, integration, or scope notes. A narrower note that says nothing about cadence remains additive and does not erase a broader affirmed methodology. A contradictory narrower methodology is an error under the strict-additive model.
For the deployment topic:
- Prefer
## Deployment. - Fall back to any heading containing
deployorrelease(case-insensitive).
For the code style topic:
- Prefer
## Code Style. - Fall back to any heading containing
styleorformat(case-insensitive).
When multiple candidate headings match by fallback, prefer the first occurrence in document order.
3. Fallback chain
For a decision that needs one operative practice statement, inspect the active-space descriptive layers from narrowest to broadest and return the first non-empty, non-conflicting section:
aidlc/spaces/<active-space>/memory/project.md— project-specific specialisation.aidlc/spaces/<active-space>/memory/team.md— team-affirmed practices.aidlc/spaces/<active-space>/memory/org.md— framework defaults written in team voice.- Hardcoded defaults — used only when all three layers are empty (greenfield first run before practices-discovery has run, or when the project SKIPs practices-discovery).
This topic selection does not erase broader rules: the runtime still loads all applicable layers. A narrower statement that contradicts broader policy is an admission error, not an override.
Hardcoded defaults are:
| Topic | Default |
|---|---|
| Way of Working | trunk-based development; base main, target main; squash-merge |
| Walking Skeleton | scope-dependent; the active scope file's skeleton: field supplies the default ceremony stance |
| Testing Posture | test-after ordering when no methodology is affirmed; the test-strategy axis governs volume |
| Deployment | trunk-based with on-merge staging deploy; production gate is human-approved |
| Code Style | defer to project linter/formatter configuration |
When the fallback chain has to descend to layer 4, emit
PRACTICES_SECTION_EMPTY (advisory-only) so doctor and downstream
observability can flag projects running on framework defaults vs affirmed
team practices.
4. Read protocol (pseudocode)
def read_practice(topic):
for layer in [
aidlc/spaces/<active-space>/memory/project.md,
aidlc/spaces/<active-space>/memory/team.md,
aidlc/spaces/<active-space>/memory/org.md,
]:
section = match_section(layer, topic) # § 2
if section and not is_empty(section): # § 1
return section
return hardcoded_default(topic) # § 3
The protocol is intentionally synchronous and side-effect-free. Agents call this when shaping a tool invocation; the orchestrator calls it when shaping a question prompt. Both surfaces use the same fallback chain so user-visible behaviour stays consistent across the dispatch.
5. Worked example — aidlc-pipeline-deploy-agent reading way-of-working
The orchestrator dispatches aidlc-pipeline-deploy-agent at Bolt-create time.
The agent's job is to map team intent to aidlc-worktree create --slug <slug> --base <branch>. It reads:
project.md## Way of Working→ empty (fresh template).team.md## Way of Working→ empty (fresh template).org.md## Way of Working→ "trunk-based; basemain, targetmain; squash-merge".- Returns
{base: "main", strategy: "squash"}to the orchestrator alongside the agent's invocation ofaidlc-worktree.
If team.md ## Way of Working had read "We use GitFlow with
develop as the integration branch", the agent would map that to
--base develop instead — same fallback chain, populated layer wins.
If all three layers were empty (a project that SKIPped practices-discovery),
the agent would emit PRACTICES_SECTION_EMPTY and apply the hardcoded
default — {base: "main", strategy: "squash"}. Doctor surfaces this so
the team can run practices-discovery later if they want their own
practices captured.